📄 teximage.c
字号:
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
/* float texture formats */
case GL_ALPHA16F_ARB:
case GL_ALPHA32F_ARB:
case GL_LUMINANCE16F_ARB:
case GL_LUMINANCE32F_ARB:
case GL_LUMINANCE_ALPHA16F_ARB:
case GL_LUMINANCE_ALPHA32F_ARB:
case GL_INTENSITY16F_ARB:
case GL_INTENSITY32F_ARB:
case GL_RGB16F_ARB:
case GL_RGB32F_ARB:
case GL_RGBA16F_ARB:
case GL_RGBA32F_ARB:
/* compressed formats */
case GL_COMPRESSED_ALPHA:
case GL_COMPRESSED_LUMINANCE:
case GL_COMPRESSED_LUMINANCE_ALPHA:
case GL_COMPRESSED_INTENSITY:
case GL_COMPRESSED_RGB:
case GL_COMPRESSED_RGBA:
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
return GL_TRUE;
case GL_YCBCR_MESA: /* not considered to be RGB */
default:
return GL_FALSE;
}
}
/**
* Test if the given image format is a color index format.
*/
static GLboolean
is_index_format(GLenum format)
{
switch (format) {
case GL_COLOR_INDEX:
case GL_COLOR_INDEX1_EXT:
case GL_COLOR_INDEX2_EXT:
case GL_COLOR_INDEX4_EXT:
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
return GL_TRUE;
default:
return GL_FALSE;
}
}
/**
* Test if the given image format is a depth component format.
*/
static GLboolean
is_depth_format(GLenum format)
{
switch (format) {
case GL_DEPTH_COMPONENT16_ARB:
case GL_DEPTH_COMPONENT24_ARB:
case GL_DEPTH_COMPONENT32_ARB:
case GL_DEPTH_COMPONENT:
return GL_TRUE;
default:
return GL_FALSE;
}
}
/**
* Test if the given image format is a YCbCr format.
*/
static GLboolean
is_ycbcr_format(GLenum format)
{
switch (format) {
case GL_YCBCR_MESA:
return GL_TRUE;
default:
return GL_FALSE;
}
}
/**
* Test if it is a supported compressed format.
*
* \param internalFormat the internal format token provided by the user.
*
* \ret GL_TRUE if \p internalFormat is a supported compressed format, or
* GL_FALSE otherwise.
*
* Currently only GL_COMPRESSED_RGB_FXT1_3DFX and GL_COMPRESSED_RGBA_FXT1_3DFX
* are supported.
*/
static GLboolean
is_compressed_format(GLcontext *ctx, GLenum internalFormat)
{
(void) ctx;
switch (internalFormat) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
return GL_TRUE;
default:
return GL_FALSE;
}
}
/**
* Store a gl_texture_image pointer in a gl_texture_object structure
* according to the target and level parameters.
*
* \param tObj texture object.
* \param target texture target.
* \param level image level.
* \param texImage texture image.
*
* This was basically prompted by the introduction of cube maps.
*/
void
_mesa_set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
struct gl_texture_image *texImage)
{
ASSERT(tObj);
ASSERT(texImage);
switch (target) {
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
tObj->Image[0][level] = texImage;
break;
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:
{
GLuint face = ((GLuint) target -
(GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
tObj->Image[face][level] = texImage;
}
break;
case GL_TEXTURE_RECTANGLE_NV:
ASSERT(level == 0);
tObj->Image[0][level] = texImage;
break;
default:
_mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
return;
}
/* Set the 'back' pointer */
texImage->TexObject = tObj;
}
/**
* Allocate a texture image structure.
*
* Called via ctx->Driver.NewTextureImage() unless overriden by a device
* driver.
*
* \return a pointer to gl_texture_image struct with all fields initialized to
* zero.
*/
struct gl_texture_image *
_mesa_new_texture_image( GLcontext *ctx )
{
(void) ctx;
return CALLOC_STRUCT(gl_texture_image);
}
/**
* Free texture image data.
* This function is a fallback called via ctx->Driver.FreeTexImageData().
*
* \param teximage texture image.
*
* Free the texture image data if it's not marked as client data.
*/
void
_mesa_free_texture_image_data(GLcontext *ctx,
struct gl_texture_image *texImage)
{
if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
_mesa_free_texmemory(texImage->Data);
}
texImage->Data = NULL;
}
/**
* Free texture image.
*
* \param teximage texture image.
*
* Free the texture image structure and the associated image data.
*/
void
_mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
{
if (texImage->Data) {
ctx->Driver.FreeTexImageData( ctx, texImage );
}
ASSERT(texImage->Data == NULL);
FREE( texImage );
}
/**
* Test if a target is a proxy target.
*
* \param target texture target.
*
* \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
*/
static GLboolean
is_proxy_target(GLenum target)
{
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
target == GL_PROXY_TEXTURE_3D ||
target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
target == GL_PROXY_TEXTURE_RECTANGLE_NV);
}
/**
* Get the texture object that corresponds to the target of the given texture unit.
*
* \param ctx GL context.
* \param texUnit texture unit.
* \param target texture target.
*
* \return pointer to the texture object on success, or NULL on failure.
*
* \sa gl_texture_unit.
*/
struct gl_texture_object *
_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
GLenum target)
{
switch (target) {
case GL_TEXTURE_1D:
return texUnit->Current1D;
case GL_PROXY_TEXTURE_1D:
return ctx->Texture.Proxy1D;
case GL_TEXTURE_2D:
return texUnit->Current2D;
case GL_PROXY_TEXTURE_2D:
return ctx->Texture.Proxy2D;
case GL_TEXTURE_3D:
return texUnit->Current3D;
case GL_PROXY_TEXTURE_3D:
return ctx->Texture.Proxy3D;
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:
return ctx->Extensions.ARB_texture_cube_map
? texUnit->CurrentCubeMap : NULL;
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Extensions.ARB_texture_cube_map
? ctx->Texture.ProxyCubeMap : NULL;
case GL_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
? texUnit->CurrentRect : NULL;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
? ctx->Texture.ProxyRect : NULL;
default:
_mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
return NULL;
}
}
/**
* Get the texture image struct which corresponds to target and level
* of the given texture unit.
*
* \param ctx GL context.
* \param texUnit texture unit.
* \param target texture target.
* \param level image level.
*
* \return pointer to the texture image structure on success, or NULL on failure.
*
* \sa gl_texture_unit.
*/
struct gl_texture_image *
_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
GLenum target, GLint level)
{
ASSERT(texUnit);
ASSERT(level < MAX_TEXTURE_LEVELS);
switch (target) {
case GL_TEXTURE_1D:
return texUnit->Current1D->Image[0][level];
case GL_PROXY_TEXTURE_1D:
return ctx->Texture.Proxy1D->Image[0][level];
case GL_TEXTURE_2D:
return texUnit->Current2D->Image[0][level];
case GL_PROXY_TEXTURE_2D:
return ctx->Texture.Proxy2D->Image[0][level];
case GL_TEXTURE_3D:
return texUnit->Current3D->Image[0][level];
case GL_PROXY_TEXTURE_3D:
return ctx->Texture.Proxy3D->Image[0][level];
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:
if (ctx->Extensions.ARB_texture_cube_map) {
GLuint face = ((GLuint) target -
(GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
return texUnit->CurrentCubeMap->Image[face][level];
}
else
return NULL;
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
if (ctx->Extensions.ARB_texture_cube_map)
return ctx->Texture.ProxyCubeMap->Image[0][level];
else
return NULL;
case GL_TEXTURE_RECTANGLE_NV:
if (ctx->Extensions.NV_texture_rectangle) {
ASSERT(level == 0);
return texUnit->CurrentRect->Image[0][level];
}
else {
return NULL;
}
case GL_PROXY_TEXTURE_RECTANGLE_NV:
if (ctx->Extensions.NV_texture_rectangle) {
ASSERT(level == 0);
return ctx->Texture.ProxyRect->Image[0][level];
}
else {
return NULL;
}
default:
_mesa_problem(ctx, "bad target in _mesa_select_tex_image()");
return NULL;
}
}
/**
* Like _mesa_select_tex_image() but if the image doesn't exist, allocate
* it and install it. Only return NULL if passed a bad parameter or run
* out of memory.
*/
struct gl_texture_image *
_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
GLenum target, GLint level)
{
struct gl_texture_image *texImage;
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!texImage) {
struct gl_texture_object *texObj;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -