diff options
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r-- | src/mesa/main/teximage.c | 177 |
1 files changed, 84 insertions, 93 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 5a60fa057fd..b28beb4ef23 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.21 2000/03/20 23:40:12 brianp Exp $ */ +/* $Id: teximage.c,v 1.22 2000/03/21 00:49:33 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -423,47 +423,45 @@ gl_free_texture_image( struct gl_texture_image *teximage ) /* - * This is called by glTexImage[123]D in order to build a gl_texture_image - * object given the client's parameters and image data. - * - * NOTES: Width, height and depth should include the border. - * All texture image parameters should have already been error checked. + * Called by glTexImage[123]D. Fill in a texture image with data given + * by the client. All pixel transfer and unpack modes are handled here. + * NOTE: All texture image parameters should have already been error checked. */ -static struct gl_texture_image * -make_texture_image( GLcontext *ctx, GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, +static void +make_texture_image( GLcontext *ctx, + struct gl_texture_image *texImage, GLenum srcFormat, GLenum srcType, const GLvoid *pixels, const struct gl_pixelstore_attrib *unpacking) { GLint components, numPixels; - struct gl_texture_image *texImage; - - assert(width > 0); - assert(height > 0); - assert(depth > 0); - assert(border == 0 || border == 1); - assert(pixels); - assert(unpacking); - - - /* - * Allocate and initialize the texture_image struct - */ - texImage = new_texture_image(width, height, depth, border, internalFormat); - if (!texImage) - return NULL; + GLint internalFormat, width, height, depth, border; + ASSERT(ctx); + ASSERT(texImage); + ASSERT(!texImage->Data); + ASSERT(pixels); + ASSERT(unpacking); + + internalFormat = texImage->IntFormat; + width = texImage->Width; + height = texImage->Height; + depth = texImage->Depth; + border = texImage->Border; components = components_in_intformat(internalFormat); - numPixels = texImage->Width * texImage->Height * texImage->Depth; - texImage->Data = (GLubyte *) MALLOC(numPixels * components + EXTRA_BYTE); + ASSERT(width > 0); + ASSERT(height > 0); + ASSERT(depth > 0); + ASSERT(border == 0 || border == 1); + ASSERT(pixels); + ASSERT(unpacking); + ASSERT(components); - if (!texImage->Data) { - /* out of memory */ - gl_free_texture_image(texImage); - return NULL; - } + numPixels = width * height * depth; + texImage->Data = (GLubyte *) MALLOC(numPixels * components + EXTRA_BYTE); + if (!texImage->Data) + return; /* out of memory */ /* * OK, the texture image struct has been initialized and the texture @@ -477,15 +475,18 @@ make_texture_image( GLcontext *ctx, GLint internalFormat, && !ctx->Pixel.IndexOffset && !ctx->Pixel.IndexShift && srcType == GL_UNSIGNED_BYTE && depth == 1) { - if (srcFormat == internalFormat) { + if (srcFormat == internalFormat || + (srcFormat == GL_LUMINANCE && internalFormat == 1) || + (srcFormat == GL_LUMINANCE_ALPHA && internalFormat == 2) || + (srcFormat == GL_RGB && internalFormat == 3) || + (srcFormat == GL_RGBA && internalFormat == 4)) { /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA, * GL_LUMINANCE_ALPHA, etc. texture formats. */ - const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking, - pixels, width, height, srcFormat, srcType, 0, 0, 0); - const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking, - pixels, width, height, srcFormat, srcType, 0, 1, 0); - const GLint srcStride = src1 - src; + const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image( + unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0); + const GLint srcStride = _mesa_image_row_stride(unpacking, width, + srcFormat, srcType); GLubyte *dst = texImage->Data; GLint dstBytesPerRow = width * components * sizeof(GLubyte); if (srcStride == dstBytesPerRow) { @@ -499,15 +500,14 @@ make_texture_image( GLcontext *ctx, GLint internalFormat, dst += dstBytesPerRow; } } - return texImage; /* all done */ + return; /* all done */ } else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) { /* commonly used by Quake */ - const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking, - pixels, width, height, srcFormat, srcType, 0, 0, 0); - const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking, - pixels, width, height, srcFormat, srcType, 0, 1, 0); - const GLint srcStride = src1 - src; + const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image( + unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0); + const GLint srcStride = _mesa_image_row_stride(unpacking, width, + srcFormat, srcType); GLubyte *dst = texImage->Data; GLint i, j; for (i = 0; i < height; i++) { @@ -520,7 +520,7 @@ make_texture_image( GLcontext *ctx, GLint internalFormat, } src += srcStride; } - return texImage; /* all done */ + return; /* all done */ } } @@ -560,8 +560,6 @@ make_texture_image( GLcontext *ctx, GLint internalFormat, } } } - - return texImage; /* All done! */ } @@ -569,26 +567,20 @@ make_texture_image( GLcontext *ctx, GLint internalFormat, /* * 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. + * spec. This function creates an empty image for the given texture image. */ -static struct gl_texture_image * -make_null_texture( GLcontext *ctx, GLenum internalFormat, - GLsizei width, GLsizei height, GLsizei depth, GLint border ) +static void +make_null_texture( struct gl_texture_image *texImage ) { GLint components; - struct gl_texture_image *texImage; GLint numPixels; - (void) ctx; - /*internalFormat = decode_internal_format(internalFormat);*/ - components = components_in_intformat(internalFormat); - numPixels = width * height * depth; + ASSERT(texImage); + ASSERT(!texImage->Data); - texImage = new_texture_image(width, height, depth, border, internalFormat); + components = components_in_intformat(texImage->IntFormat); + numPixels = texImage->Width * texImage->Height * texImage->Depth; - /* It's easier later if we really do have a texture image, rather than - * a NULL image pointer. - */ texImage->Data = (GLubyte *) MALLOC( numPixels * components + EXTRA_BYTE ); /* @@ -610,9 +602,9 @@ make_null_texture( GLcontext *ctx, GLenum internalFormat, GLubyte *imgPtr = texImage->Data; GLint i, j, k; - for (i=0;i<height;i++) { + for (i = 0; i < texImage->Height; i++) { GLint srcRow = 7 - i % 8; - for (j=0;j<width;j++) { + for (j = 0; j < texImage->Width; j++) { GLint srcCol = j % 32; GLint texel = (message[srcRow][srcCol]=='X') ? 255 : 70; for (k=0;k<components;k++) { @@ -621,8 +613,6 @@ make_null_texture( GLcontext *ctx, GLenum internalFormat, } } } - - return texImage; } @@ -1041,7 +1031,7 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, * Called from the API. Note that width includes the border. */ void -_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, +_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { @@ -1052,7 +1042,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, struct gl_texture_unit *texUnit; struct gl_texture_image *teximage; - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 1, width, 1, 1, border )) { return; /* error in texture image was detected */ } @@ -1064,14 +1054,14 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, gl_free_texture_image( texUnit->CurrentD[1]->Image[level] ); } + teximage = new_texture_image(width, 1, 1, border, internalFormat); + /* make new texture from source image */ if (pixels) { - teximage = make_texture_image(ctx, internalformat, width, 1, 1, - border, format, type, pixels, &ctx->Unpack); + make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack); } else { - teximage = make_null_texture(ctx, (GLenum) internalformat, - width, 1, 1, border); + make_null_texture(teximage); } /* install new texture image */ @@ -1083,12 +1073,12 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, if (ctx->Driver.TexImage) { (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texUnit->CurrentD[1], - level, internalformat, teximage ); + level, internalFormat, teximage ); } } else if (target==GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 1, width, 1, 1, border )) { if (level>=0 && level<ctx->Const.MaxTextureLevels) { MEMSET( ctx->Texture.Proxy1D->Image[level], 0, @@ -1098,7 +1088,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, else { ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) format; set_teximage_component_sizes( ctx->Texture.Proxy1D->Image[level] ); - ctx->Texture.Proxy1D->Image[level]->IntFormat = (GLenum) internalformat; + ctx->Texture.Proxy1D->Image[level]->IntFormat = (GLenum) internalFormat; ctx->Texture.Proxy1D->Image[level]->Border = border; ctx->Texture.Proxy1D->Image[level]->Width = width; ctx->Texture.Proxy1D->Image[level]->Height = 1; @@ -1113,7 +1103,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, void -_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, +_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) @@ -1125,7 +1115,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, struct gl_texture_unit *texUnit; struct gl_texture_image *teximage; - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 2, width, height, 1, border )) { return; /* error in texture image was detected */ } @@ -1137,14 +1127,14 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, gl_free_texture_image( texUnit->CurrentD[2]->Image[level] ); } + teximage = new_texture_image(width, height, 1, border,internalFormat); + /* make new texture from source image */ if (pixels) { - teximage = make_texture_image(ctx, internalformat, width, height, 1, - border, format, type, pixels, &ctx->Unpack); + make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack); } else { - teximage = make_null_texture(ctx, (GLenum) internalformat, - width, height, 1, border); + make_null_texture(teximage); } /* install new texture image */ @@ -1156,12 +1146,12 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, if (ctx->Driver.TexImage) { (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texUnit->CurrentD[2], - level, internalformat, teximage ); + level, internalFormat, teximage ); } } else if (target==GL_PROXY_TEXTURE_2D) { /* Proxy texture: check for errors and update proxy state */ - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 2, width, height, 1, border )) { if (level>=0 && level<ctx->Const.MaxTextureLevels) { MEMSET( ctx->Texture.Proxy2D->Image[level], 0, @@ -1171,7 +1161,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, else { ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) format; set_teximage_component_sizes( ctx->Texture.Proxy2D->Image[level] ); - ctx->Texture.Proxy2D->Image[level]->IntFormat = (GLenum) internalformat; + ctx->Texture.Proxy2D->Image[level]->IntFormat = (GLenum) internalFormat; ctx->Texture.Proxy2D->Image[level]->Border = border; ctx->Texture.Proxy2D->Image[level]->Width = width; ctx->Texture.Proxy2D->Image[level]->Height = height; @@ -1191,7 +1181,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, * Note that width and height include the border. */ void -_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, +_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) @@ -1202,7 +1192,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, if (target==GL_TEXTURE_3D_EXT) { struct gl_texture_unit *texUnit; struct gl_texture_image *teximage; - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 3, width, height, depth, border )) { return; /* error in texture image was detected */ @@ -1215,14 +1205,15 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, gl_free_texture_image( texUnit->CurrentD[3]->Image[level] ); } + teximage = new_texture_image(width, height, depth, + border, internalFormat); + /* make new texture from source image */ if (pixels) { - teximage = make_texture_image(ctx, internalformat, width, height, - depth, border, format, type, pixels, &ctx->Unpack); + make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack); } else { - teximage = make_null_texture(ctx, (GLenum) internalformat, - width, height, depth, border); + make_null_texture(teximage); } /* install new texture image */ @@ -1234,12 +1225,12 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, if (ctx->Driver.TexImage) { (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texUnit->CurrentD[3], - level, internalformat, teximage ); + level, internalFormat, teximage ); } } else if (target==GL_PROXY_TEXTURE_3D_EXT) { /* Proxy texture: check for errors and update proxy state */ - if (texture_error_check( ctx, target, level, internalformat, + if (texture_error_check( ctx, target, level, internalFormat, format, type, 3, width, height, depth, border )) { if (level>=0 && level<ctx->Const.MaxTextureLevels) { @@ -1250,7 +1241,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, else { ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) format; set_teximage_component_sizes( ctx->Texture.Proxy3D->Image[level] ); - ctx->Texture.Proxy3D->Image[level]->IntFormat = (GLenum) internalformat; + ctx->Texture.Proxy3D->Image[level]->IntFormat = (GLenum) internalFormat; ctx->Texture.Proxy3D->Image[level]->Border = border; ctx->Texture.Proxy3D->Image[level]->Width = width; ctx->Texture.Proxy3D->Image[level]->Height = height; @@ -1265,12 +1256,12 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, void -_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, +_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { - _mesa_TexImage3D(target, level, (GLint) internalformat, width, height, + _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, depth, border, format, type, pixels); } |