📄 texobj.c
字号:
/* 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) || (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) { maxLog2 = t->Image[0][baseLevel]->WidthLog2; maxLevels = ctx->Const.MaxTextureLevels; } else if ((t->Target == GL_TEXTURE_2D) || (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { 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 */ 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) || (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) { /* 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) || (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { /* 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 *//*@{*//** * 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(). * * 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(ctx->Shared->Mutex); 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(ctx->Shared->Mutex); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); return; } /* insert into hash table */ _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); textures[i] = name; } _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);}/** * 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 (revert to default textures). */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) { _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D); } else if (texObj == unit->Current2D) { _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D); } else if (texObj == unit->Current3D) { _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D); } else if (texObj == unit->CurrentCubeMap) { _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); } else if (texObj == unit->CurrentRect) { _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -