texobj.c

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

C
1,053
字号
             * If so, unbind.             * See section 4.4.2.3 of GL_EXT_framebuffer_object.             */            unbind_texobj_from_fbo(ctx, delObj);            /* Check if this texture is currently bound to any texture units.             * If so, unbind it and decrement the reference count.             */            unbind_texobj_from_texunits(ctx, delObj);            ctx->NewState |= _NEW_TEXTURE;            /* The texture _name_ is now free for re-use.             * Remove it from the hash table now.             */            _glthread_LOCK_MUTEX(ctx->Shared->Mutex);            _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);            _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);            /* The actual texture object will not be freed until it's no             * longer bound in any context.             * XXX all RefCount accesses should be protected by a mutex.             */            delObj->RefCount--;            if (delObj->RefCount == 0) {               ASSERT(delObj->Name != 0); /* Never delete default tex objs */               ASSERT(ctx->Driver.DeleteTexture);               (*ctx->Driver.DeleteTexture)(ctx, delObj);            }         }      }   }}/** * Bind a named texture to a texturing target. *  * \param target texture target. * \param texName texture name. *  * \sa glBindTexture(). * * Determines the old texture object bound and returns immediately if rebinding * the same texture.  Get the current texture which is either a default texture * if name is null, a named texture from the hash, or a new texture if the * given texture name is new. Increments its reference count, binds it, and * calls dd_function_table::BindTexture. Decrements the old texture reference * count and deletes it if it reaches zero. */void GLAPIENTRY_mesa_BindTexture( GLenum target, GLuint texName ){   GET_CURRENT_CONTEXT(ctx);   GLuint unit = ctx->Texture.CurrentUnit;   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *oldTexObj;   struct gl_texture_object *newTexObj = NULL;   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))      _mesa_debug(ctx, "glBindTexture %s %d\n",                  _mesa_lookup_enum_by_nr(target), (GLint) texName);   /*    * Get pointer to currently bound texture object (oldTexObj)    */   switch (target) {      case GL_TEXTURE_1D:         oldTexObj = texUnit->Current1D;         break;      case GL_TEXTURE_2D:         oldTexObj = texUnit->Current2D;         break;      case GL_TEXTURE_3D:         oldTexObj = texUnit->Current3D;         break;      case GL_TEXTURE_CUBE_MAP_ARB:         if (!ctx->Extensions.ARB_texture_cube_map) {            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );            return;         }         oldTexObj = texUnit->CurrentCubeMap;         break;      case GL_TEXTURE_RECTANGLE_NV:         if (!ctx->Extensions.NV_texture_rectangle) {            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );            return;         }         oldTexObj = texUnit->CurrentRect;         break;      default:         _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );         return;   }   if (oldTexObj->Name == texName)      /* XXX this might be wrong.  If the texobj is in use by another       * context and a texobj parameter was changed, this might be our       * only chance to update this context's hardware state.       */      return;   /* rebinding the same texture- no change */   /*    * Get pointer to new texture object (newTexObj)    */   if (texName == 0) {      /* newTexObj = a default texture object */      switch (target) {         case GL_TEXTURE_1D:            newTexObj = ctx->Shared->Default1D;            break;         case GL_TEXTURE_2D:            newTexObj = ctx->Shared->Default2D;            break;         case GL_TEXTURE_3D:            newTexObj = ctx->Shared->Default3D;            break;         case GL_TEXTURE_CUBE_MAP_ARB:            newTexObj = ctx->Shared->DefaultCubeMap;            break;         case GL_TEXTURE_RECTANGLE_NV:            newTexObj = ctx->Shared->DefaultRect;            break;         default:            ; /* Bad targets are caught above */      }   }   else {      /* non-default texture object */      newTexObj = _mesa_lookup_texture(ctx, texName);      if (newTexObj) {         /* error checking */         if (newTexObj->Target != 0 && newTexObj->Target != target) {            /* the named texture object's dimensions don't match the target */            _mesa_error( ctx, GL_INVALID_OPERATION,                         "glBindTexture(wrong dimensionality)" );            return;         }         if (newTexObj->Target == 0 && target == GL_TEXTURE_RECTANGLE_NV) {            /* have to init wrap and filter state here - kind of klunky */            newTexObj->WrapS = GL_CLAMP_TO_EDGE;            newTexObj->WrapT = GL_CLAMP_TO_EDGE;            newTexObj->WrapR = GL_CLAMP_TO_EDGE;            newTexObj->MinFilter = GL_LINEAR;            if (ctx->Driver.TexParameter) {               static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};               static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_S, fparam_wrap );               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_T, fparam_wrap );               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_R, fparam_wrap );               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_MIN_FILTER, fparam_filter );            }         }      }      else {         /* if this is a new texture id, allocate a texture object now */	 newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target);         if (!newTexObj) {            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");            return;         }         /* and insert it into hash table */         _glthread_LOCK_MUTEX(ctx->Shared->Mutex);         _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);      }      newTexObj->Target = target;   }   /* XXX all RefCount accesses should be protected by a mutex. */   newTexObj->RefCount++;   /* do the actual binding, but first flush outstanding vertices:    */   FLUSH_VERTICES(ctx, _NEW_TEXTURE);   switch (target) {      case GL_TEXTURE_1D:         texUnit->Current1D = newTexObj;         break;      case GL_TEXTURE_2D:         texUnit->Current2D = newTexObj;         break;      case GL_TEXTURE_3D:         texUnit->Current3D = newTexObj;         break;      case GL_TEXTURE_CUBE_MAP_ARB:         texUnit->CurrentCubeMap = newTexObj;         break;      case GL_TEXTURE_RECTANGLE_NV:         texUnit->CurrentRect = newTexObj;         break;      default:         _mesa_problem(ctx, "bad target in BindTexture");         return;   }   /* Pass BindTexture call to device driver */   if (ctx->Driver.BindTexture)      (*ctx->Driver.BindTexture)( ctx, target, newTexObj );   /* Decrement the reference count on the old texture and check if it's    * time to delete it.    */   /* XXX all RefCount accesses should be protected by a mutex. */   oldTexObj->RefCount--;   ASSERT(oldTexObj->RefCount >= 0);   if (oldTexObj->RefCount == 0) {      ASSERT(oldTexObj->Name != 0);      ASSERT(ctx->Driver.DeleteTexture);      (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );   }}/** * Set texture priorities. *  * \param n number of textures. * \param texName texture names. * \param priorities corresponding texture priorities. *  * \sa glPrioritizeTextures(). *  * Looks up each texture in the hash, clamps the corresponding priority between * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture. */void GLAPIENTRY_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,                          const GLclampf *priorities ){   GET_CURRENT_CONTEXT(ctx);   GLint i;   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);   if (n < 0) {      _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );      return;   }   if (!priorities)      return;   for (i = 0; i < n; i++) {      if (texName[i] > 0) {         struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);         if (t) {            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );	    if (ctx->Driver.PrioritizeTexture)	       ctx->Driver.PrioritizeTexture( ctx, t, t->Priority );         }      }   }   ctx->NewState |= _NEW_TEXTURE;}/** * See if textures are loaded in texture memory. *  * \param n number of textures to query. * \param texName array with the texture names. * \param residences array which will hold the residence status. * * \return GL_TRUE if all textures are resident and \p residences is left unchanged,  *  * \sa glAreTexturesResident(). * * Looks up each texture in the hash and calls * dd_function_table::IsTextureResident. */GLboolean GLAPIENTRY_mesa_AreTexturesResident(GLsizei n, const GLuint *texName,                          GLboolean *residences){   GET_CURRENT_CONTEXT(ctx);   GLboolean allResident = GL_TRUE;   GLint i, j;   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);   if (n < 0) {      _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");      return GL_FALSE;   }   if (!texName || !residences)      return GL_FALSE;   for (i = 0; i < n; i++) {      struct gl_texture_object *t;      if (texName[i] == 0) {         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");         return GL_FALSE;      }      t = _mesa_lookup_texture(ctx, texName[i]);      if (!t) {         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");         return GL_FALSE;      }      if (!ctx->Driver.IsTextureResident ||          ctx->Driver.IsTextureResident(ctx, t)) {         /* The texture is resident */	 if (!allResident)	    residences[i] = GL_TRUE;      }      else {         /* The texture is not resident */         if (allResident) {	    allResident = GL_FALSE;	    for (j = 0; j < i; j++)	       residences[j] = GL_TRUE;	 }	 residences[i] = GL_FALSE;      }   }      return allResident;}/** * See if a name corresponds to a texture. * * \param texture texture name. * * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE * otherwise. *  * \sa glIsTexture(). * * Calls _mesa_HashLookup(). */GLboolean GLAPIENTRY_mesa_IsTexture( GLuint texture ){   struct gl_texture_object *t;   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);   if (!texture)      return GL_FALSE;   t = _mesa_lookup_texture(ctx, texture);   /* IsTexture is true only after object has been bound once. */   return t && t->Target;}/*@}*/

⌨️ 快捷键说明

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