diff options
author | Brian Paul <[email protected]> | 2001-05-21 16:41:03 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2001-05-21 16:41:03 +0000 |
commit | 3893e638e6521b9c070e01c0b31d22754ff97a88 (patch) | |
tree | f92282e8466199dd45c72e6725c3fa0263bae2e0 /src/mesa/main | |
parent | e7e38a47a8dd567fd5a848cbef09b14018fb2fe0 (diff) |
initial support for GL_SGIS_generate_mipmap extension
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/context.c | 3 | ||||
-rw-r--r-- | src/mesa/main/extensions.c | 4 | ||||
-rw-r--r-- | src/mesa/main/get.c | 46 | ||||
-rw-r--r-- | src/mesa/main/hint.c | 18 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 14 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 84 | ||||
-rw-r--r-- | src/mesa/main/teximage.h | 15 | ||||
-rw-r--r-- | src/mesa/main/texstate.c | 93 | ||||
-rw-r--r-- | src/mesa/main/texstore.c | 410 | ||||
-rw-r--r-- | src/mesa/main/texstore.h | 7 |
10 files changed, 594 insertions, 100 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index f855b90f3ce..d7cdf10b00a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.137 2001/05/07 16:32:51 brianp Exp $ */ +/* $Id: context.c,v 1.138 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -918,6 +918,7 @@ init_attrib_groups( GLcontext *ctx ) ctx->Hint.Fog = GL_DONT_CARE; ctx->Hint.ClipVolumeClipping = GL_DONT_CARE; ctx->Hint.TextureCompression = GL_DONT_CARE; + ctx->Hint.GenerateMipmap = GL_DONT_CARE; /* Histogram group */ ctx->Histogram.Width = 0; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 3a082678149..8faeb090963 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,4 +1,4 @@ -/* $Id: extensions.c,v 1.58 2001/04/24 21:52:36 brianp Exp $ */ +/* $Id: extensions.c,v 1.59 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -106,6 +106,7 @@ static struct { { ON, "GL_NV_texgen_reflection", F(NV_texgen_reflection) }, { OFF, "GL_SGI_color_matrix", F(SGI_color_matrix) }, { OFF, "GL_SGI_color_table", F(SGI_color_table) }, + /*{ OFF, "GL_SGIS_generate_mipmap", F(SGIS_generate_mipmap) },*/ { OFF, "GL_SGIS_pixel_texture", F(SGIS_pixel_texture) }, { OFF, "GL_SGIS_texture_border_clamp", F(ARB_texture_border_clamp) }, { OFF, "GL_SGIS_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, @@ -158,6 +159,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) "GL_NV_texgen_reflection", "GL_SGI_color_matrix", "GL_SGI_color_table", + "GL_SGIS_generate_mipmap", "GL_SGIS_pixel_texture", "GL_SGIS_texture_edge_clamp", "GL_SGIS_texture_border_clamp", diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 1e9b7be3ce6..b16343831db 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1,4 +1,4 @@ -/* $Id: get.c,v 1.59 2001/05/03 23:55:38 brianp Exp $ */ +/* $Id: get.c,v 1.60 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1280,6 +1280,17 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) } break; + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = ENUM_TO_BOOL(ctx->Hint.GenerateMipmap); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" ); } @@ -2484,6 +2495,17 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) } break; + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLdouble) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" ); } @@ -3662,6 +3684,17 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) } break; + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLfloat) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" ); } @@ -4889,6 +4922,17 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) } break; + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLint) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + break; + default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); } diff --git a/src/mesa/main/hint.c b/src/mesa/main/hint.c index ce0b27394fa..e37cfb1a87d 100644 --- a/src/mesa/main/hint.c +++ b/src/mesa/main/hint.c @@ -1,4 +1,4 @@ -/* $Id: hint.c,v 1.9 2001/03/12 00:48:38 gareth Exp $ */ +/* $Id: hint.c,v 1.10 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -99,9 +99,9 @@ _mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode ) /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSION_HINT_ARB: - if (ctx->Extensions.ARB_texture_compression) { + if (!ctx->Extensions.ARB_texture_compression) { _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); - return GL_TRUE; + return GL_FALSE; } if (ctx->Hint.TextureCompression == mode) return GL_TRUE; @@ -109,6 +109,18 @@ _mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode ) ctx->Hint.TextureCompression = mode; break; + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (!ctx->Extensions.SGIS_generate_mipmap) { + _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); + return GL_FALSE; + } + if (ctx->Hint.GenerateMipmap == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.GenerateMipmap = mode; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); return GL_FALSE; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 651b6bb7b95..b8c2ec7af6e 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $Id: mtypes.h,v 1.41 2001/04/28 08:39:17 keithw Exp $ */ +/* $Id: mtypes.h,v 1.42 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -430,12 +430,9 @@ struct gl_hint_attrib { GLenum LineSmooth; GLenum PolygonSmooth; GLenum Fog; - - /* GL_EXT_clip_volume_hint */ - GLenum ClipVolumeClipping; - - /* GL_ARB_texture_compression */ - GLenum TextureCompression; + GLenum ClipVolumeClipping; /* GL_EXT_clip_volume_hint */ + GLenum TextureCompression; /* GL_ARB_texture_compression */ + GLenum GenerateMipmap; /* GL_SGIS_generate_mipmap */ }; @@ -826,6 +823,8 @@ struct gl_texture_object { GLchan ShadowAmbient; /* GL_SGIX_shadow_ambient */ GLint _MaxLevel; /* actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /* = _MaxLevel - BaseLevel (q - b in spec) */ + GLboolean GenerateMipmap; /* GL_SGIS_generate_mipmap */ + struct gl_texture_image *Image[MAX_TEXTURE_LEVELS]; /* Texture cube faces */ @@ -1218,6 +1217,7 @@ struct gl_extensions { GLboolean NV_texgen_reflection; GLboolean SGI_color_matrix; GLboolean SGI_color_table; + GLboolean SGIS_generate_mipmap; GLboolean SGIS_pixel_texture; GLboolean SGIS_texture_edge_clamp; GLboolean SGIX_depth_texture; diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 723d74d7aae..2f1d4383926 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.93 2001/04/24 03:00:17 brianp Exp $ */ +/* $Id: teximage.c,v 1.94 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -39,6 +39,7 @@ #include "texformat.h" #include "teximage.h" #include "texstate.h" +#include "texstore.h" #include "mtypes.h" #include "swrast/s_span.h" /* XXX SWRAST hack */ #endif @@ -319,10 +320,10 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat) * according to the target and level parameters. * This was basically prompted by the introduction of cube maps. */ -static void -set_tex_image(struct gl_texture_object *tObj, - GLenum target, GLint level, - struct gl_texture_image *texImage) +void +_mesa_set_tex_image(struct gl_texture_object *tObj, + GLenum target, GLint level, + struct gl_texture_image *texImage) { ASSERT(tObj); ASSERT(texImage); @@ -349,7 +350,7 @@ set_tex_image(struct gl_texture_object *tObj, tObj->NegZ[level] = texImage; return; default: - _mesa_problem(NULL, "bad target in set_tex_image()"); + _mesa_problem(NULL, "bad target in _mesa_set_tex_image()"); return; } } @@ -581,11 +582,11 @@ clear_teximage_fields(struct gl_texture_image *img) /* * Initialize basic fields of the gl_texture_image struct. */ -static void -init_teximage_fields(GLcontext *ctx, - struct gl_texture_image *img, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum internalFormat) +void +_mesa_init_teximage_fields(GLcontext *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat) { ASSERT(img); img->Format = _mesa_base_tex_format( ctx, internalFormat ); @@ -1324,8 +1325,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); @@ -1368,8 +1369,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1425,7 +1426,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, if (!texImage) { texImage = _mesa_alloc_texture_image(); - set_tex_image(texObj, target, level, texImage); + _mesa_set_tex_image(texObj, target, level, texImage); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; @@ -1437,8 +1438,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, + 1, border, internalFormat); if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); @@ -1481,8 +1482,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, + postConvHeight, 1, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1542,8 +1543,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - init_teximage_fields(ctx, texImage, width, height, depth, border, - internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, + internalFormat); if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); @@ -1587,8 +1588,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, width, height, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1788,7 +1789,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); if (!texImage) { texImage = _mesa_alloc_texture_image(); - set_tex_image(texObj, target, level, texImage); + _mesa_set_tex_image(texObj, target, level, texImage); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); return; @@ -1801,8 +1802,8 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, } clear_teximage_fields(texImage); /* not really needed, but helpful */ - init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); ASSERT(ctx->Driver.CopyTexImage1D); @@ -1852,7 +1853,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, texImage = _mesa_select_tex_image(ctx, texUnit, target, level); if (!texImage) { texImage = _mesa_alloc_texture_image(); - set_tex_image(texObj, target, level, texImage); + _mesa_set_tex_image(texObj, target, level, texImage); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); return; @@ -1865,8 +1866,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, } clear_teximage_fields(texImage); /* not really needed, but helpful */ - init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, + border, internalFormat); ASSERT(ctx->Driver.CopyTexImage2D); (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, @@ -2049,7 +2050,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texImage->Data = NULL; } - init_teximage_fields(ctx, texImage, width, 1, 1, border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + border, internalFormat); if (ctx->Extensions.ARB_texture_compression) { ASSERT(ctx->Driver.CompressedTexImage1D); @@ -2073,8 +2075,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, width, 1, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, @@ -2147,8 +2149,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texImage->Data = NULL; } - init_teximage_fields(ctx, texImage, width, height, 1, border, - internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border, + internalFormat); if (ctx->Extensions.ARB_texture_compression) { ASSERT(ctx->Driver.CompressedTexImage2D); @@ -2172,8 +2174,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, width, height, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, @@ -2243,8 +2245,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texImage->Data = NULL; } - init_teximage_fields(ctx, texImage, width, height, depth, border, - internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, + internalFormat); if (ctx->Extensions.ARB_texture_compression) { ASSERT(ctx->Driver.CompressedTexImage3D); @@ -2269,8 +2271,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - init_teximage_fields(ctx, texImage, width, height, depth, - border, internalFormat); + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, GL_NONE, GL_NONE, diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index b5664e4efaa..12c6c99e5fe 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -1,4 +1,4 @@ -/* $Id: teximage.h,v 1.18 2001/03/26 20:02:39 brianp Exp $ */ +/* $Id: teximage.h,v 1.19 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -47,6 +47,19 @@ extern void _mesa_free_texture_image( struct gl_texture_image *teximage ); +extern void +_mesa_init_teximage_fields(GLcontext *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat); + + +extern void +_mesa_set_tex_image(struct gl_texture_object *tObj, + GLenum target, GLint level, + struct gl_texture_image *texImage); + + extern struct gl_texture_object * _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, GLenum target); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 2a4a9a9f96d..afa3d07753d 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,4 +1,4 @@ -/* $Id: texstate.c,v 1.50 2001/05/18 22:10:49 brianp Exp $ */ +/* $Id: texstate.c,v 1.51 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1043,6 +1043,15 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) return; } break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" ); return; @@ -1272,25 +1281,25 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = ENUM_TO_FLOAT(obj->MagFilter); - break; + return; case GL_TEXTURE_MIN_FILTER: *params = ENUM_TO_FLOAT(obj->MinFilter); - break; + return; case GL_TEXTURE_WRAP_S: *params = ENUM_TO_FLOAT(obj->WrapS); - break; + return; case GL_TEXTURE_WRAP_T: *params = ENUM_TO_FLOAT(obj->WrapT); - break; + return; case GL_TEXTURE_WRAP_R_EXT: *params = ENUM_TO_FLOAT(obj->WrapR); - break; + return; case GL_TEXTURE_BORDER_COLOR: params[0] = obj->BorderColor[0] / CHAN_MAXF; params[1] = obj->BorderColor[1] / CHAN_MAXF; params[2] = obj->BorderColor[2] / CHAN_MAXF; params[3] = obj->BorderColor[3] / CHAN_MAXF; - break; + return; case GL_TEXTURE_RESIDENT: { GLboolean resident; @@ -1300,52 +1309,51 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) resident = GL_TRUE; *params = ENUM_TO_FLOAT(resident); } - break; + return; case GL_TEXTURE_PRIORITY: *params = obj->Priority; - break; + return; case GL_TEXTURE_MIN_LOD: *params = obj->MinLod; - break; + return; case GL_TEXTURE_MAX_LOD: *params = obj->MaxLod; - break; + return; case GL_TEXTURE_BASE_LEVEL: *params = (GLfloat) obj->BaseLevel; - break; + return; case GL_TEXTURE_MAX_LEVEL: *params = (GLfloat) obj->MaxLevel; - break; + return; case GL_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareFlag; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" ); return; } break; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareOperator; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" ); return; } break; case GL_SHADOW_AMBIENT_SGIX: if (ctx->Extensions.SGIX_shadow_ambient) { *params = CHAN_TO_FLOAT(obj->ShadowAmbient); + return; } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)"); + break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLfloat) obj->GenerateMipmap; return; } break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" ); + ; /* silence warnings */ } + /* If we get here, pname was an unrecognized enum */ + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" ); } @@ -1366,19 +1374,19 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = (GLint) obj->MagFilter; - break; + return; case GL_TEXTURE_MIN_FILTER: *params = (GLint) obj->MinFilter; - break; + return; case GL_TEXTURE_WRAP_S: *params = (GLint) obj->WrapS; - break; + return; case GL_TEXTURE_WRAP_T: *params = (GLint) obj->WrapT; - break; + return; case GL_TEXTURE_WRAP_R_EXT: *params = (GLint) obj->WrapR; - break; + return; case GL_TEXTURE_BORDER_COLOR: { GLfloat color[4]; @@ -1391,7 +1399,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) params[2] = FLOAT_TO_INT( color[2] ); params[3] = FLOAT_TO_INT( color[3] ); } - break; + return; case GL_TEXTURE_RESIDENT: { GLboolean resident; @@ -1401,37 +1409,31 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) resident = GL_TRUE; *params = (GLint) resident; } - break; + return; case GL_TEXTURE_PRIORITY: *params = (GLint) obj->Priority; - break; + return; case GL_TEXTURE_MIN_LOD: *params = (GLint) obj->MinLod; - break; + return; case GL_TEXTURE_MAX_LOD: *params = (GLint) obj->MaxLod; - break; + return; case GL_TEXTURE_BASE_LEVEL: *params = obj->BaseLevel; - break; + return; case GL_TEXTURE_MAX_LEVEL: *params = obj->MaxLevel; - break; + return; case GL_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLint) obj->CompareFlag; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" ); return; } break; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLint) obj->CompareOperator; - } - else { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" ); return; } break; @@ -1439,15 +1441,20 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) if (ctx->Extensions.SGIX_shadow_ambient) { /* XXX range? */ *params = (GLint) CHAN_TO_FLOAT(obj->ShadowAmbient); + return; } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)"); + break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLint) obj->GenerateMipmap; return; } break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" ); + ; /* silence warnings */ } + /* If we get here, pname was an unrecognized enum */ + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" ); } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index bfa23018cf7..e3a4b108271 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,4 +1,4 @@ -/* $Id: texstore.c,v 1.24 2001/04/20 16:46:04 brianp Exp $ */ +/* $Id: texstore.c,v 1.25 2001/05/21 16:41:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -642,6 +642,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, 0, /* dstRowStride */ 0, /* dstImageStride */ format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -674,6 +680,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, internalFormat, format, type); assert(texImage->TexFormat); + texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; texelBytes = texImage->TexFormat->TexelBytes; @@ -691,6 +698,12 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, texImage->Width * texelBytes, 0, /* dstImageStride */ format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -735,6 +748,12 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, texImage->Width * texelBytes, texImage->Width * texImage->Height * texelBytes, format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -759,6 +778,12 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, 0, /* dstRowStride */ 0, /* dstImageStride */ format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -782,6 +807,12 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, texImage->Width * texImage->TexFormat->TexelBytes, 0, /* dstImageStride */ format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -806,6 +837,11 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, texImage->Width * texelBytes, texImage->Width * texImage->Height * texelBytes, format, type, pixels, packing); + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } } @@ -898,3 +934,375 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, return GL_TRUE; } + + + +/* + * Average together two rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source rows are to be twice as long as the + * dest row. + */ +static void +do_row(const struct gl_texture_format *format, GLint dstWidth, + const GLvoid *srcRowA, const GLvoid *srcRowB, GLvoid *dstRow) +{ + switch (format->MesaFormat) { + case MESA_FORMAT_RGBA: + { + GLuint i, j; + const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; + const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; + GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; + for (i = j = 0; i < dstWidth; i++, j+=2) { + dst[i][0] = (rowA[j][0] + rowA[j+1][0] + + rowB[j][0] + rowB[j+1][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[j+1][1] + + rowB[j][1] + rowB[j+1][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[j+1][2] + + rowB[j][2] + rowB[j+1][2]) >> 2; + dst[i][3] = (rowA[j][3] + rowA[j+1][3] + + rowB[j][3] + rowB[j+1][3]) >> 2; + } + } + return; + case MESA_FORMAT_RGB: + { + GLuint i, j; + const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; + const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; + GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; + for (i = j = 0; i < dstWidth; i++, j+=2) { + dst[i][0] = (rowA[j][0] + rowA[j+1][0] + + rowB[j][0] + rowB[j+1][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[j+1][1] + + rowB[j][1] + rowB[j+1][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[j+1][2] + + rowB[j][2] + rowB[j+1][2]) >> 2; + } + } + return; + case MESA_FORMAT_ALPHA: + case MESA_FORMAT_LUMINANCE: + case MESA_FORMAT_INTENSITY: + case MESA_FORMAT_COLOR_INDEX: + { + GLuint i, j; + const GLchan *rowA = (const GLchan *) srcRowA; + const GLchan *rowB = (const GLchan *) srcRowB; + GLchan *dst = (GLchan *) dstRow; + for (i = j = 0; i < dstWidth; i++, j+=2) { + dst[i] = (rowA[j] + rowA[j+1] + rowB[j] + rowB[j+1]) >> 2; + } + } + return; + case MESA_FORMAT_LUMINANCE_ALPHA: + { + GLuint i, j; + const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; + const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; + GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; + for (i = j = 0; i < dstWidth; i++, j+=2) { + dst[i][0] = (rowA[j][0] + rowA[j+1][0] + + rowB[j][0] + rowB[j+1][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[j+1][1] + + rowB[j][1] + rowB[j+1][1]) >> 2; + } + } + return; + case MESA_FORMAT_DEPTH_COMPONENT: + + /* XXX do hardware texture formats */ + + default: + _mesa_problem(NULL, "bad format in do_row()"); + } +} + + + + +static void +make_1d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, const GLubyte *srcPtr, + GLint dstWidth, GLubyte *dstPtr) +{ + const GLint bpt = format->TexelBytes; + const GLubyte *src; + GLubyte *dst; + + /* skip the border pixel, if any */ + src = srcPtr + border * bpt; + dst = dstPtr + border * bpt; + + /* we just duplicate the input row, kind of hack, saves code */ + do_row(format, dstWidth - 2 * border, src, src, dst); + + if (border) { + /* copy left-most pixel from source */ + MEMCPY(dstPtr, srcPtr, bpt); + /* copy right-most pixel from source */ + MEMCPY(dstPtr + (dstWidth - 1) * bpt, + srcPtr + (srcWidth - 1) * bpt, + bpt); + } +} + + +static void +make_2d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, + GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) +{ + const GLint bpt = format->TexelBytes; + const GLint srcRowStride = bpt * srcWidth; + const GLint dstRowStride = bpt * dstWidth; + const GLubyte *srcA, *srcB; + GLubyte *dst; + GLint row; + + /* Compute src and dst pointers, skipping any border */ + srcA = srcPtr + border * ((srcWidth + 1) * bpt); + if (srcHeight > 1) + srcB = srcA + srcRowStride; + else + srcB = srcA; + dst = dstPtr + border * ((dstWidth + 1) * bpt); + + for (row = 0; row < dstHeight - 2 * border; row++) { + do_row(format, dstWidth - 2 * border, srcA, srcB, dst); + srcA += 2 * srcRowStride; + srcB += 2 * srcRowStride; + dst += dstRowStride; + } + + if (border > 0) { + /* fill in dest border */ + /* lower-left border pixel */ + MEMCPY(dstPtr, srcPtr, bpt); + /* lower-right border pixel */ + MEMCPY(dstPtr + (dstWidth - 1) * bpt, + srcPtr + (srcWidth - 1) * bpt, bpt); + /* upper-left border pixel */ + MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, + srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); + /* upper-right border pixel */ + MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, + srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); + /* lower border */ + do_row(format, dstWidth - 2 * border, + srcPtr + bpt, srcPtr + bpt, dstPtr + bpt); + /* upper border */ + do_row(format, dstWidth - 2 * border, + srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, + srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, + dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); + /* left and right borders */ + for (row = 0; row < dstHeight - 2 * border; row += 2) { + GLubyte tempPixel[32]; + GLint srcOffset; + srcOffset = (srcWidth * (row * 2 + 1)) * bpt; + MEMCPY(tempPixel, srcPtr + srcOffset, bpt); + srcOffset = (srcWidth * (row * 2 + 2)) * bpt; + MEMCPY(tempPixel + bpt, srcPtr + srcOffset, bpt); + do_row(format, 1, tempPixel, tempPixel, + dstPtr + (dstWidth * row + 1) * bpt); + srcOffset = (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt; + MEMCPY(tempPixel, srcPtr + srcOffset, bpt); + srcOffset = (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt; + MEMCPY(tempPixel, srcPtr + srcOffset, bpt); + do_row(format, 1, tempPixel, tempPixel, + dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); + } + } +} + + +static void +make_3d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + const GLubyte *srcPtr, + GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLubyte *dstPtr) +{ + GLvoid *tmpRowA = MALLOC(dstWidth * format->TexelBytes); + GLvoid *tmpRowB = MALLOC(dstWidth * format->TexelBytes); + const GLubyte *srcA, *srcB, *srcC, *srcD; + GLint img, row; + + if (!tmpRowA || !tmpRowB) { + if (tmpRowA) + FREE(tmpRowA); + return; + } + + /* + * XXX lots of work to do here yet + */ + + for (img = 0; img < dstDepth - 2 * border; img++) { + + for (row = 0; row < dstHeight - 2 * border; row++) { + do_row(format, dstWidth - 2 * border, srcA, srcB, tmpRowA); + do_row(format, dstWidth - 2 * border, srcC, srcD, tmpRowB); + + + } + } + + FREE(tmpRowA); + FREE(tmpRowB); +} + + +/* + * For GL_SGIX_generate_mipmap: + * Generate a complete set of mipmaps from texObj's base-level image. + * Stop at texObj's MaxLevel or when we get to the 1x1 texture. + */ +void +_mesa_generate_mipmap(GLcontext *ctx, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj) +{ + const GLenum targets1D[] = { GL_TEXTURE_1D, 0 }; + const GLenum targets2D[] = { GL_TEXTURE_2D, 0 }; + const GLenum targets3D[] = { GL_TEXTURE_3D, 0 }; + const GLenum targetsCube[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, + 0 }; + const GLenum *targets; + GLuint level; + + ASSERT(texObj); + ASSERT(texObj->Image[texObj->BaseLevel]); + + switch (texObj->Dimensions) { + case 1: + targets = targets1D; + break; + case 2: + targets = targets2D; + break; + case 3: + targets = targets3D; + break; + case 6: + targets = targetsCube; + break; + default: + _mesa_problem(ctx, + "Bad texture object dimension in _mesa_generate_mipmaps"); + return; + } + + for (level = texObj->BaseLevel; level < texObj->MaxLevel; level++) { + /* generate level+1 from level */ + const struct gl_texture_image *srcImage; + struct gl_texture_image *dstImage; + GLint srcWidth, srcHeight, srcDepth; + GLint dstWidth, dstHeight, dstDepth; + GLint border, bytesPerTexel; + GLint t; + + srcImage = texObj->Image[level]; + ASSERT(srcImage); + srcWidth = srcImage->Width; + srcHeight = srcImage->Height; + srcDepth = srcImage->Depth; + border = srcImage->Border; + bytesPerTexel = srcImage->TexFormat->TexelBytes; + + /* compute next (level+1) image size */ + if (srcWidth - 2 * border > 1) { + dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; + } + else { + dstWidth = srcWidth; /* can't go smaller */ + } + if (srcHeight - 2 * border > 1) { + dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; + } + else { + dstHeight = srcHeight; /* can't go smaller */ + } + if (srcDepth - 2 * border > 1) { + dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; + } + else { + dstDepth = srcDepth; /* can't go smaller */ + } + + if (dstWidth == srcWidth && + dstHeight == srcHeight && + dstDepth == srcDepth) { + /* all done */ + return; + } + + /* Need this loop just because of cubemaps */ + for (t = 0; targets[t]; t++) { + ASSERT(t < 6); + + dstImage = _mesa_select_tex_image(ctx, texUnit, targets[t], level+1); + if (!dstImage) { + dstImage = _mesa_alloc_texture_image(); + if (!dstImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + _mesa_set_tex_image(texObj, targets[t], level + 1, dstImage); + } + + /* Free old image data */ + if (dstImage->Data) + FREE(dstImage->Data); + + /* initialize new image */ + _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight, + dstDepth, border, srcImage->Format); + dstImage->DriverData = NULL; + dstImage->TexFormat = srcImage->TexFormat; + dstImage->FetchTexel = srcImage->FetchTexel; + + ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); + + /* alloc new image buffer */ + dstImage->Data = MALLOC(dstWidth * dstHeight * dstDepth + * bytesPerTexel); + if (!dstImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + + /* + * We use simple 2x2 averaging to compute the next mipmap level. + */ + switch (texObj->Dimensions) { + case 1: + make_1d_mipmap(srcImage->TexFormat, border, + srcWidth, (const GLubyte *) srcImage->Data, + dstWidth, (GLubyte *) dstImage->Data); + break; + case 2: + case 6: + make_2d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, (const GLubyte *) srcImage->Data, + dstWidth, dstHeight, (GLubyte *) dstImage->Data); + break; + case 3: + make_3d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, srcDepth, (const GLubyte *) srcImage->Data, + dstWidth, dstHeight, dstDepth, (GLubyte *) dstImage->Data); + break; + default: + _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); + return; + } + } /* loop over tex image targets */ + } /* loop over tex levels */ +} diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index ba868341606..4d62a015f03 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -1,4 +1,4 @@ -/* $Id: texstore.h,v 1.7 2001/04/20 16:46:04 brianp Exp $ */ +/* $Id: texstore.h,v 1.8 2001/05/21 16:41:04 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -141,4 +141,9 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint width, GLint height, GLint depth, GLint border); +extern void +_mesa_generate_mipmap(GLcontext *ctx, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj); + #endif |