texobj.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,053 行 · 第 1/3 页
C
1,053 行
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]->_BaseFormat == 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]->_BaseFormat == 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);}/** * Check if the given texture object is bound to the current draw or * read framebuffer. If so, Unbind it. */static voidunbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj){ const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2; GLuint i; for (i = 0; i < n; i++) { struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer; if (fb->Name) { GLuint j; for (j = 0; j < BUFFER_COUNT; j++) { if (fb->Attachment[j].Type == GL_TEXTURE && fb->Attachment[j].Texture == texObj) { _mesa_remove_attachment(ctx, fb->Attachment + j); } } } }}/** * Check if the given texture object is bound to any texture image units and * unbind it if so. * XXX all RefCount accesses should be protected by a mutex. */static voidunbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj){ GLuint u; for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; if (texObj == unit->Current1D) { unit->Current1D = ctx->Shared->Default1D; ctx->Shared->Default1D->RefCount++; texObj->RefCount--; if (texObj == unit->_Current) unit->_Current = unit->Current1D; } else if (texObj == unit->Current2D) { unit->Current2D = ctx->Shared->Default2D; ctx->Shared->Default2D->RefCount++; texObj->RefCount--; if (texObj == unit->_Current) unit->_Current = unit->Current2D; } else if (texObj == unit->Current3D) { unit->Current3D = ctx->Shared->Default3D; ctx->Shared->Default3D->RefCount++; texObj->RefCount--; if (texObj == unit->_Current) unit->_Current = unit->Current3D; } else if (texObj == unit->CurrentCubeMap) { unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; ctx->Shared->DefaultCubeMap->RefCount++; texObj->RefCount--; if (texObj == unit->_Current) unit->_Current = unit->CurrentCubeMap; } else if (texObj == unit->CurrentRect) { unit->CurrentRect = ctx->Shared->DefaultRect; ctx->Shared->DefaultRect->RefCount++; texObj->RefCount--; if (texObj == unit->_Current) unit->_Current = unit->CurrentRect; } }}/** * 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 = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { /* Check if texture is bound to any framebuffer objects.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?