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

📄 texobj.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
         t->Complete = GL_FALSE;
         incomplete(t, "minLevel > maxLevel");
         return;
      }

      /* Test dimension-independent attributes */
      for (i = minLevel; i <= maxLevel; i++) {
         if (t->Image[0][i]) {
            if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
               t->Complete = GL_FALSE;
               incomplete(t, "Format[i] != Format[baseLevel]");
               return;
            }
            if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
               t->Complete = GL_FALSE;
               incomplete(t, "Border[i] != Border[baseLevel]");
               return;
            }
         }
      }

      /* Test things which depend on number of texture image dimensions */
      if (t->Target == GL_TEXTURE_1D) {
         /* Test 1-D mipmaps */
         GLuint width = t->Image[0][baseLevel]->Width2;
         for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[0][i]) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "1D Image[0][i] == NULL");
                  return;
               }
               if (t->Image[0][i]->Width2 != width ) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "1D Image[0][i] bad width");
                  return;
               }
            }
            if (width == 1) {
               return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_2D) {
         /* Test 2-D mipmaps */
         GLuint width = t->Image[0][baseLevel]->Width2;
         GLuint height = t->Image[0][baseLevel]->Height2;
         for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[0][i]) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[0][i] == NULL");
                  return;
               }
               if (t->Image[0][i]->Width2 != width) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[0][i] bad width");
                  return;
               }
               if (t->Image[0][i]->Height2 != height) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[0][i] bad height");
                  return;
               }
               if (width==1 && height==1) {
                  return;  /* found smallest needed mipmap, all done! */
               }
            }
         }
      }
      else if (t->Target == GL_TEXTURE_3D) {
         /* Test 3-D mipmaps */
         GLuint width = t->Image[0][baseLevel]->Width2;
         GLuint height = t->Image[0][baseLevel]->Height2;
         GLuint depth = t->Image[0][baseLevel]->Depth2;
	 for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (depth > 1) {
               depth /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[0][i]) {
                  incomplete(t, "3D Image[0][i] == NULL");
                  t->Complete = GL_FALSE;
                  return;
               }
               if (t->Image[0][i]->Format == GL_DEPTH_COMPONENT) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
                  return;
               }
               if (t->Image[0][i]->Width2 != width) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[0][i] bad width");
                  return;
               }
               if (t->Image[0][i]->Height2 != height) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[0][i] bad height");
                  return;
               }
               if (t->Image[0][i]->Depth2 != depth) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[0][i] bad depth");
                  return;
               }
            }
            if (width == 1 && height == 1 && depth == 1) {
               return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
         /* make sure 6 cube faces are consistant */
         GLuint width = t->Image[0][baseLevel]->Width2;
         GLuint height = t->Image[0][baseLevel]->Height2;
	 for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
	       GLuint face;
	       for (face = 0; face < 6; face++) {
		  /* check that we have images defined */
		  if (!t->Image[face][i]) {
		     t->Complete = GL_FALSE;
		     incomplete(t, "CubeMap Image[n][i] == NULL");
		     return;
		  }
		  /* Don't support GL_DEPTH_COMPONENT for cube maps */
		  if (t->Image[face][i]->Format == GL_DEPTH_COMPONENT) {
		     t->Complete = GL_FALSE;
		     incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
		     return;
		  }
		  /* check that all six images have same size */
		  if (t->Image[face][i]->Width2!=width || 
		      t->Image[face][i]->Height2!=height) {
		     t->Complete = GL_FALSE;
		     incomplete(t, "CubeMap Image[n][i] bad size");
		     return;
		  }
	       }
	    }
	    if (width == 1 && height == 1) {
	       return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
         /* XXX special checking? */
      }
      else {
         /* Target = ??? */
         _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
      }
   }
}

/*@}*/


/***********************************************************************/
/** \name API functions */
/*@{*/

/**
 * Texture name generation lock.
 *
 * Used by _mesa_GenTextures() to guarantee that the generation and allocation
 * of texture IDs is atomic.
 */
_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);

/**
 * Generate texture names.
 *
 * \param n number of texture names to be generated.
 * \param textures an array in which will hold the generated texture names.
 *
 * \sa glGenTextures().
 *
 * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock()
 * to find a block of free texture IDs which are stored in \p textures.
 * Corresponding empty texture objects are also generated.
 */ 
void GLAPIENTRY
_mesa_GenTextures( GLsizei n, GLuint *textures )
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
      return;
   }

   if (!textures)
      return;

   /*
    * This must be atomic (generation and allocation of texture IDs)
    */
   _glthread_LOCK_MUTEX(GenTexturesLock);

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);

   /* Allocate new, empty texture objects */
   for (i = 0; i < n; i++) {
      struct gl_texture_object *texObj;
      GLuint name = first + i;
      GLenum target = 0;
      texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
      if (!texObj) {
         _glthread_UNLOCK_MUTEX(GenTexturesLock);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
         return;
      }

      /* insert into hash table */
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);

      textures[i] = name;
   }

   _glthread_UNLOCK_MUTEX(GenTexturesLock);
}


/**
 * Delete named textures.
 *
 * \param n number of textures to be deleted.
 * \param textures array of texture IDs to be deleted.
 *
 * \sa glDeleteTextures().
 *
 * If we're about to delete a texture that's currently bound to any
 * texture unit, unbind the texture first.  Decrement the reference
 * count on the texture object and delete it if it's zero.
 * Recall that texture objects can be shared among several rendering
 * contexts.
 */
void GLAPIENTRY
_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */

   if (!textures)
      return;

   for (i = 0; i < n; i++) {
      if (textures[i] > 0) {
         struct gl_texture_object *delObj = (struct gl_texture_object *)
            _mesa_HashLookup(ctx->Shared->TexObjects, textures[i]);
         if (delObj) {
            /* First check if this texture is currently bound.
             * If so, unbind it and decrement the reference count.
             * XXX all RefCount accesses should be protected by a mutex.
             */
            GLuint u;
            for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
               struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
               if (delObj == unit->Current1D) {
                  unit->Current1D = ctx->Shared->Default1D;
                  ctx->Shared->Default1D->RefCount++;
                  delObj->RefCount--;
                  if (delObj == unit->_Current)
                     unit->_Current = unit->Current1D;
               }
               else if (delObj == unit->Current2D) {
                  unit->Current2D = ctx->Shared->Default2D;
                  ctx->Shared->Default2D->RefCount++;
                  delObj->RefCount--;
                  if (delObj == unit->_Current)
                     unit->_Current = unit->Current2D;
               }
               else if (delObj == unit->Current3D) {
                  unit->Current3D = ctx->Shared->Default3D;
                  ctx->Shared->Default3D->RefCount++;
                  delObj->RefCount--;
                  if (delObj == unit->_Current)
                     unit->_Current = unit->Current3D;
               }
               else if (delObj == unit->CurrentCubeMap) {
                  unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
                  ctx->Shared->DefaultCubeMap->RefCount++;
                  delObj->RefCount--;
                  if (delObj == unit->_Current)
                     unit->_Current = unit->CurrentCubeMap;
               }
               else if (delObj == unit->CurrentRect) {
                  unit->CurrentRect = ctx->Shared->DefaultRect;
                  ctx->Shared->DefaultRect->RefCount++;
                  delObj->RefCount--;
                  if (delObj == unit->_Current)
                     unit->_Current = unit->CurrentRect;
               }
            }
            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.

⌨️ 快捷键说明

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