-/* $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
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;
-/* $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
{ 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) },
"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",
-/* $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
}
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" );
}
}
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" );
}
}
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" );
}
}
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" );
}
-/* $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
/* 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;
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;
-/* $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
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 */
};
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 */
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;
-/* $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
#include "texformat.h"
#include "teximage.h"
#include "texstate.h"
+#include "texstore.h"
#include "mtypes.h"
#include "swrast/s_span.h" /* XXX SWRAST hack */
#endif
* 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);
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;
}
}
/*
* 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 );
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);
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,
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;
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);
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,
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);
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,
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;
}
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);
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;
}
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,
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);
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,
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);
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,
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);
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,
-/* $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
_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);
-/* $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
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;
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;
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)" );
}
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];
params[2] = FLOAT_TO_INT( color[2] );
params[3] = FLOAT_TO_INT( color[3] );
}
- break;
+ return;
case GL_TEXTURE_RESIDENT:
{
GLboolean resident;
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;
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)" );
}
-/* $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
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);
+ }
}
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
internalFormat, format, type);
assert(texImage->TexFormat);
+ texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
texelBytes = texImage->TexFormat->TexelBytes;
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);
+ }
}
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);
+ }
}
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);
+ }
}
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);
+ }
}
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);
+ }
}
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 */
+}
-/* $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
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
-/* $Id: s_texstore.c,v 1.4 2001/05/03 22:13:32 brianp Exp $ */
+/* $Id: s_texstore.c,v 1.5 2001/05/21 16:41:04 brianp Exp $ */
/*
* Mesa 3-D graphics library
#include "mem.h"
#include "texformat.h"
#include "teximage.h"
+#include "texstore.h"
#include "s_context.h"
#include "s_depth.h"
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, texUnit, texObj);
+ }
}
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, texUnit, texObj);
+ }
}
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, texUnit, texObj);
+ }
}
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, texUnit, texObj);
+ }
}
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, texUnit, texObj);
+ }
}