⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texobj.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
             */
            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 */
      const struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
      newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, 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 = (struct gl_texture_object *)
            _mesa_HashLookup(ctx->Shared->TexObjects, 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 = (struct gl_texture_object *)
         _mesa_HashLookup(ctx->Shared->TexObjects, 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 = (struct gl_texture_object *)
      _mesa_HashLookup(ctx->Shared->TexObjects, texture);

   /* IsTexture is true only after object has been bound once. */
   return t && t->Target;
}

/*@}*/

⌨️ 快捷键说明

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