📄 teximage.c
字号:
texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); return NULL; } texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); _mesa_set_tex_image(texObj, target, level, texImage); } return texImage;}/** * Return pointer to the specified proxy texture image. * Note that proxy textures are per-context, not per-texture unit. * \return pointer to texture image or NULL if invalid target, invalid * level, or out of memory. */struct gl_texture_image *_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level){ struct gl_texture_image *texImage; if (level < 0 ) return NULL; switch (target) { case GL_PROXY_TEXTURE_1D: if (level >= ctx->Const.MaxTextureLevels) return NULL; texImage = ctx->Texture.Proxy1D->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } ctx->Texture.Proxy1D->Image[0][level] = texImage; /* Set the 'back' pointer */ texImage->TexObject = ctx->Texture.Proxy1D; } return texImage; case GL_PROXY_TEXTURE_2D: if (level >= ctx->Const.MaxTextureLevels) return NULL; texImage = ctx->Texture.Proxy2D->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } ctx->Texture.Proxy2D->Image[0][level] = texImage; /* Set the 'back' pointer */ texImage->TexObject = ctx->Texture.Proxy2D; } return texImage; case GL_PROXY_TEXTURE_3D: if (level >= ctx->Const.Max3DTextureLevels) return NULL; texImage = ctx->Texture.Proxy3D->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } ctx->Texture.Proxy3D->Image[0][level] = texImage; /* Set the 'back' pointer */ texImage->TexObject = ctx->Texture.Proxy3D; } return texImage; case GL_PROXY_TEXTURE_CUBE_MAP: if (level >= ctx->Const.MaxCubeTextureLevels) return NULL; texImage = ctx->Texture.ProxyCubeMap->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } ctx->Texture.ProxyCubeMap->Image[0][level] = texImage; /* Set the 'back' pointer */ texImage->TexObject = ctx->Texture.ProxyCubeMap; } return texImage; case GL_PROXY_TEXTURE_RECTANGLE_NV: if (level > 0) return NULL; texImage = ctx->Texture.ProxyRect->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } ctx->Texture.ProxyRect->Image[0][level] = texImage; /* Set the 'back' pointer */ texImage->TexObject = ctx->Texture.ProxyRect; } return texImage; default: return NULL; }}/** * Get the maximum number of allowed mipmap levels. * * \param ctx GL context. * \param target texture target. * * \return the maximum number of allowed mipmap levels for the given * texture target, or zero if passed a bad target. * * \sa gl_constants. */GLint_mesa_max_texture_levels(GLcontext *ctx, GLenum target){ switch (target) { case GL_TEXTURE_1D: case GL_PROXY_TEXTURE_1D: case GL_TEXTURE_2D: case GL_PROXY_TEXTURE_2D: return ctx->Const.MaxTextureLevels; case GL_TEXTURE_3D: case GL_PROXY_TEXTURE_3D: return ctx->Const.Max3DTextureLevels; case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: case GL_TEXTURE_CUBE_MAP_ARB: case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Const.MaxCubeTextureLevels; case GL_TEXTURE_RECTANGLE_NV: case GL_PROXY_TEXTURE_RECTANGLE_NV: return 1; default: return 0; /* bad target */ }}#if 000 /* not used anymore *//* * glTexImage[123]D can accept a NULL image pointer. In this case we * create a texture image with unspecified image contents per the OpenGL * spec. */static GLubyte *make_null_texture(GLint width, GLint height, GLint depth, GLenum format){ const GLint components = _mesa_components_in_format(format); const GLint numPixels = width * height * depth; GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));#ifdef DEBUG /* * Let's see if anyone finds this. If glTexImage2D() is called with * a NULL image pointer then load the texture image with something * interesting instead of leaving it indeterminate. */ if (data) { static const char message[8][32] = { " X X XXXXX XXX X ", " XX XX X X X X X ", " X X X X X X X ", " X X XXXX XXX XXXXX ", " X X X X X X ", " X X X X X X X ", " X X XXXXX XXX X X ", " " }; GLubyte *imgPtr = data; GLint h, i, j, k; for (h = 0; h < depth; h++) { for (i = 0; i < height; i++) { GLint srcRow = 7 - (i % 8); for (j = 0; j < width; j++) { GLint srcCol = j % 32; GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; for (k = 0; k < components; k++) { *imgPtr++ = texel; } } } } }#endif return data;}#endif/** * Reset the fields of a gl_texture_image struct to zero. * * \param img texture image structure. * * This is called when a proxy texture test fails, we set all the * image members (except DriverData) to zero. * It's also used in glTexImage[123]D as a safeguard to be sure all * required fields get initialized properly by the Driver.TexImage[123]D * functions. */static voidclear_teximage_fields(struct gl_texture_image *img){ ASSERT(img); img->_BaseFormat = 0; img->InternalFormat = 0; img->Border = 0; img->Width = 0; img->Height = 0; img->Depth = 0; img->RowStride = 0; img->ImageStride = 0; img->Width2 = 0; img->Height2 = 0; img->Depth2 = 0; img->WidthLog2 = 0; img->HeightLog2 = 0; img->DepthLog2 = 0; img->Data = NULL; img->TexFormat = &_mesa_null_texformat; img->FetchTexelc = NULL; img->FetchTexelf = NULL; img->IsCompressed = 0; img->CompressedSize = 0;}/** * Initialize basic fields of the gl_texture_image struct. * * \param ctx GL context. * \param target texture target. * \param img texture image structure to be initialized. * \param width image width. * \param height image height. * \param depth image depth. * \param border image border. * \param internalFormat internal format. * * Fills in the fields of \p img with the given information. * Note: width, height and depth include the border. */void_mesa_init_teximage_fields(GLcontext *ctx, GLenum target, struct gl_texture_image *img, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum internalFormat){ ASSERT(img); img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); ASSERT(img->_BaseFormat > 0); img->InternalFormat = internalFormat; img->Border = border; img->Width = width; img->Height = height; img->Depth = depth; img->RowStride = width; img->ImageStride = width * height; img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ img->WidthLog2 = logbase2(img->Width2); if (height == 1) /* 1-D texture */ img->HeightLog2 = 0; else img->HeightLog2 = logbase2(img->Height2); if (depth == 1) /* 2-D texture */ img->DepthLog2 = 0; else img->DepthLog2 = logbase2(img->Depth2); img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); img->IsCompressed = is_compressed_format(ctx, internalFormat); if (img->IsCompressed) img->CompressedSize = ctx->Driver.CompressedTextureSize(ctx, width, height, depth, internalFormat); else img->CompressedSize = 0; if ((width == 1 || _mesa_bitcount(img->Width2) == 1) && (height == 1 || _mesa_bitcount(img->Height2) == 1) && (depth == 1 || _mesa_bitcount(img->Depth2) == 1)) img->_IsPowerOfTwo = GL_TRUE; else img->_IsPowerOfTwo = GL_FALSE; /* Compute Width/Height/DepthScale for mipmap lod computation */ if (target == GL_TEXTURE_RECTANGLE_NV) { /* scale = 1.0 since texture coords directly map to texels */ img->WidthScale = 1.0; img->HeightScale = 1.0; img->DepthScale = 1.0; } else { img->WidthScale = (GLfloat) img->Width; img->HeightScale = (GLfloat) img->Height; img->DepthScale = (GLfloat) img->Depth; }}/** * This is the fallback for Driver.TestProxyTexImage(). Test the texture * level, width, height and depth against the ctx->Const limits for textures. * * A hardware driver might override this function if, for example, the * max 3D texture size is 512x512x64 (i.e. not a cube). * * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D, * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV, * GL_PROXY_TEXTURE_CUBE_MAP_ARB. * \param level as passed to glTexImage * \param internalFormat as passed to glTexImage * \param format as passed to glTexImage * \param type as passed to glTexImage * \param width as passed to glTexImage * \param height as passed to glTexImage * \param depth as passed to glTexImage * \param border as passed to glTexImage * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. */GLboolean_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, GLint depth, GLint border){ GLint maxSize; (void) internalFormat; (void) format; (void) type; switch (target) { case GL_PROXY_TEXTURE_1D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width - 2 * border) != 1) || level >= ctx->Const.MaxTextureLevels) { /* bad width or level */ return GL_FALSE; } return GL_TRUE; case GL_PROXY_TEXTURE_2D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width - 2 * border) != 1) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height - 2 * border) != 1) || level >= ctx->Const.MaxTextureLevels) { /* bad width or height or level */ return GL_FALSE; } return GL_TRUE; case GL_PROXY_TEXTURE_3D: maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width - 2 * border) != 1) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height - 2 * border) != 1) || depth < 2 * border || depth > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(depth - 2 * border) != 1) || level >= ctx->Const.Max3DTextureLevels) { /* bad width or height or depth or level */ return GL_FALSE; } return GL_TRUE; case GL_PROXY_TEXTURE_RECTANGLE_NV: if (width < 1 || width > ctx->Const.MaxTextureRectSize || height < 1 || height > ctx->Const.MaxTextureRectSize || level != 0) { /* bad width or height or level */ return GL_FALSE; } return GL_TRUE; case GL_PROXY_TEXTURE_CUBE_MAP_ARB: maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width - 2 * border) != 1) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height - 2 * border) != 1) || level >= ctx->Const.MaxCubeTextureLevels) { /* bad width or height */ return GL_FALSE; } return GL_TRUE; default: _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); return GL_FALSE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -