clean-up of texture image construction

This commit is contained in:
Brian Paul
2000-03-21 00:49:33 +00:00
parent ae40595b69
commit 43911c8ef0

View File

@@ -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 * 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 * Called by glTexImage[123]D. Fill in a texture image with data given
* object given the client's parameters and image data. * by the client. All pixel transfer and unpack modes are handled here.
* * NOTE: All texture image parameters should have already been error checked.
* NOTES: Width, height and depth should include the border.
* All texture image parameters should have already been error checked.
*/ */
static struct gl_texture_image * static void
make_texture_image( GLcontext *ctx, GLint internalFormat, make_texture_image( GLcontext *ctx,
GLint width, GLint height, GLint depth, GLint border, struct gl_texture_image *texImage,
GLenum srcFormat, GLenum srcType, const GLvoid *pixels, GLenum srcFormat, GLenum srcType, const GLvoid *pixels,
const struct gl_pixelstore_attrib *unpacking) const struct gl_pixelstore_attrib *unpacking)
{ {
GLint components, numPixels; GLint components, numPixels;
struct gl_texture_image *texImage; GLint internalFormat, width, height, depth, border;
assert(width > 0); ASSERT(ctx);
assert(height > 0); ASSERT(texImage);
assert(depth > 0); ASSERT(!texImage->Data);
assert(border == 0 || border == 1); ASSERT(pixels);
assert(pixels); ASSERT(unpacking);
assert(unpacking);
/*
* Allocate and initialize the texture_image struct
*/
texImage = new_texture_image(width, height, depth, border, internalFormat);
if (!texImage)
return NULL;
internalFormat = texImage->IntFormat;
width = texImage->Width;
height = texImage->Height;
depth = texImage->Depth;
border = texImage->Border;
components = components_in_intformat(internalFormat); components = components_in_intformat(internalFormat);
numPixels = texImage->Width * texImage->Height * texImage->Depth;
ASSERT(width > 0);
ASSERT(height > 0);
ASSERT(depth > 0);
ASSERT(border == 0 || border == 1);
ASSERT(pixels);
ASSERT(unpacking);
ASSERT(components);
numPixels = width * height * depth;
texImage->Data = (GLubyte *) MALLOC(numPixels * components + EXTRA_BYTE); texImage->Data = (GLubyte *) MALLOC(numPixels * components + EXTRA_BYTE);
if (!texImage->Data)
if (!texImage->Data) { return; /* out of memory */
/* out of memory */
gl_free_texture_image(texImage);
return NULL;
}
/* /*
* OK, the texture image struct has been initialized and the texture * 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 && !ctx->Pixel.IndexOffset && !ctx->Pixel.IndexShift
&& srcType == GL_UNSIGNED_BYTE && depth == 1) { && 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, /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
* GL_LUMINANCE_ALPHA, etc. texture formats. * GL_LUMINANCE_ALPHA, etc. texture formats.
*/ */
const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking, const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(
pixels, width, height, srcFormat, srcType, 0, 0, 0); unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0);
const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking, const GLint srcStride = _mesa_image_row_stride(unpacking, width,
pixels, width, height, srcFormat, srcType, 0, 1, 0); srcFormat, srcType);
const GLint srcStride = src1 - src;
GLubyte *dst = texImage->Data; GLubyte *dst = texImage->Data;
GLint dstBytesPerRow = width * components * sizeof(GLubyte); GLint dstBytesPerRow = width * components * sizeof(GLubyte);
if (srcStride == dstBytesPerRow) { if (srcStride == dstBytesPerRow) {
@@ -499,15 +500,14 @@ make_texture_image( GLcontext *ctx, GLint internalFormat,
dst += dstBytesPerRow; dst += dstBytesPerRow;
} }
} }
return texImage; /* all done */ return; /* all done */
} }
else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) { else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) {
/* commonly used by Quake */ /* commonly used by Quake */
const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(unpacking, const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image(
pixels, width, height, srcFormat, srcType, 0, 0, 0); unpacking, pixels, width, height, srcFormat, srcType, 0, 0, 0);
const GLubyte *src1 = (const GLubyte *) gl_pixel_addr_in_image(unpacking, const GLint srcStride = _mesa_image_row_stride(unpacking, width,
pixels, width, height, srcFormat, srcType, 0, 1, 0); srcFormat, srcType);
const GLint srcStride = src1 - src;
GLubyte *dst = texImage->Data; GLubyte *dst = texImage->Data;
GLint i, j; GLint i, j;
for (i = 0; i < height; i++) { for (i = 0; i < height; i++) {
@@ -520,7 +520,7 @@ make_texture_image( GLcontext *ctx, GLint internalFormat,
} }
src += srcStride; 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 * glTexImage[123]D can accept a NULL image pointer. In this case we
* create a texture image with unspecified image contents per the OpenGL * 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 * static void
make_null_texture( GLcontext *ctx, GLenum internalFormat, make_null_texture( struct gl_texture_image *texImage )
GLsizei width, GLsizei height, GLsizei depth, GLint border )
{ {
GLint components; GLint components;
struct gl_texture_image *texImage;
GLint numPixels; GLint numPixels;
(void) ctx;
/*internalFormat = decode_internal_format(internalFormat);*/ ASSERT(texImage);
components = components_in_intformat(internalFormat); ASSERT(!texImage->Data);
numPixels = width * height * depth;
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 ); texImage->Data = (GLubyte *) MALLOC( numPixels * components + EXTRA_BYTE );
/* /*
@@ -610,9 +602,9 @@ make_null_texture( GLcontext *ctx, GLenum internalFormat,
GLubyte *imgPtr = texImage->Data; GLubyte *imgPtr = texImage->Data;
GLint i, j, k; GLint i, j, k;
for (i=0;i<height;i++) { for (i = 0; i < texImage->Height; i++) {
GLint srcRow = 7 - i % 8; GLint srcRow = 7 - i % 8;
for (j=0;j<width;j++) { for (j = 0; j < texImage->Width; j++) {
GLint srcCol = j % 32; GLint srcCol = j % 32;
GLint texel = (message[srcRow][srcCol]=='X') ? 255 : 70; GLint texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
for (k=0;k<components;k++) { 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. * Called from the API. Note that width includes the border.
*/ */
void void
_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLint border, GLenum format, GLsizei width, GLint border, GLenum format,
GLenum type, const GLvoid *pixels ) 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_unit *texUnit;
struct gl_texture_image *teximage; 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 )) { format, type, 1, width, 1, 1, border )) {
return; /* error in texture image was detected */ 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] ); gl_free_texture_image( texUnit->CurrentD[1]->Image[level] );
} }
teximage = new_texture_image(width, 1, 1, border, internalFormat);
/* make new texture from source image */ /* make new texture from source image */
if (pixels) { if (pixels) {
teximage = make_texture_image(ctx, internalformat, width, 1, 1, make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
border, format, type, pixels, &ctx->Unpack);
} }
else { else {
teximage = make_null_texture(ctx, (GLenum) internalformat, make_null_texture(teximage);
width, 1, 1, border);
} }
/* install new texture image */ /* install new texture image */
@@ -1083,12 +1073,12 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
if (ctx->Driver.TexImage) { if (ctx->Driver.TexImage) {
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
texUnit->CurrentD[1], texUnit->CurrentD[1],
level, internalformat, teximage ); level, internalFormat, teximage );
} }
} }
else if (target==GL_PROXY_TEXTURE_1D) { else if (target==GL_PROXY_TEXTURE_1D) {
/* Proxy texture: check for errors and update proxy state */ /* 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 )) { format, type, 1, width, 1, 1, border )) {
if (level>=0 && level<ctx->Const.MaxTextureLevels) { if (level>=0 && level<ctx->Const.MaxTextureLevels) {
MEMSET( ctx->Texture.Proxy1D->Image[level], 0, MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
@@ -1098,7 +1088,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
else { else {
ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) format; ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) format;
set_teximage_component_sizes( ctx->Texture.Proxy1D->Image[level] ); 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]->Border = border;
ctx->Texture.Proxy1D->Image[level]->Width = width; ctx->Texture.Proxy1D->Image[level]->Width = width;
ctx->Texture.Proxy1D->Image[level]->Height = 1; ctx->Texture.Proxy1D->Image[level]->Height = 1;
@@ -1113,7 +1103,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
void void
_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, GLenum format, GLenum type,
const GLvoid *pixels ) const GLvoid *pixels )
@@ -1125,7 +1115,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
struct gl_texture_unit *texUnit; struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage; 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 )) { format, type, 2, width, height, 1, border )) {
return; /* error in texture image was detected */ 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] ); gl_free_texture_image( texUnit->CurrentD[2]->Image[level] );
} }
teximage = new_texture_image(width, height, 1, border,internalFormat);
/* make new texture from source image */ /* make new texture from source image */
if (pixels) { if (pixels) {
teximage = make_texture_image(ctx, internalformat, width, height, 1, make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
border, format, type, pixels, &ctx->Unpack);
} }
else { else {
teximage = make_null_texture(ctx, (GLenum) internalformat, make_null_texture(teximage);
width, height, 1, border);
} }
/* install new texture image */ /* install new texture image */
@@ -1156,12 +1146,12 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
if (ctx->Driver.TexImage) { if (ctx->Driver.TexImage) {
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
texUnit->CurrentD[2], texUnit->CurrentD[2],
level, internalformat, teximage ); level, internalFormat, teximage );
} }
} }
else if (target==GL_PROXY_TEXTURE_2D) { else if (target==GL_PROXY_TEXTURE_2D) {
/* Proxy texture: check for errors and update proxy state */ /* 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 )) { format, type, 2, width, height, 1, border )) {
if (level>=0 && level<ctx->Const.MaxTextureLevels) { if (level>=0 && level<ctx->Const.MaxTextureLevels) {
MEMSET( ctx->Texture.Proxy2D->Image[level], 0, MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
@@ -1171,7 +1161,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
else { else {
ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) format; ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) format;
set_teximage_component_sizes( ctx->Texture.Proxy2D->Image[level] ); 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]->Border = border;
ctx->Texture.Proxy2D->Image[level]->Width = width; ctx->Texture.Proxy2D->Image[level]->Width = width;
ctx->Texture.Proxy2D->Image[level]->Height = height; 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. * Note that width and height include the border.
*/ */
void void
_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, GLint border, GLenum format, GLenum type,
const GLvoid *pixels ) const GLvoid *pixels )
@@ -1202,7 +1192,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
if (target==GL_TEXTURE_3D_EXT) { if (target==GL_TEXTURE_3D_EXT) {
struct gl_texture_unit *texUnit; struct gl_texture_unit *texUnit;
struct gl_texture_image *teximage; 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, format, type, 3, width, height, depth,
border )) { border )) {
return; /* error in texture image was detected */ 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] ); gl_free_texture_image( texUnit->CurrentD[3]->Image[level] );
} }
teximage = new_texture_image(width, height, depth,
border, internalFormat);
/* make new texture from source image */ /* make new texture from source image */
if (pixels) { if (pixels) {
teximage = make_texture_image(ctx, internalformat, width, height, make_texture_image(ctx, teximage, format, type, pixels, &ctx->Unpack);
depth, border, format, type, pixels, &ctx->Unpack);
} }
else { else {
teximage = make_null_texture(ctx, (GLenum) internalformat, make_null_texture(teximage);
width, height, depth, border);
} }
/* install new texture image */ /* install new texture image */
@@ -1234,12 +1225,12 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
if (ctx->Driver.TexImage) { if (ctx->Driver.TexImage) {
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
texUnit->CurrentD[3], texUnit->CurrentD[3],
level, internalformat, teximage ); level, internalFormat, teximage );
} }
} }
else if (target==GL_PROXY_TEXTURE_3D_EXT) { else if (target==GL_PROXY_TEXTURE_3D_EXT) {
/* Proxy texture: check for errors and update proxy state */ /* 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, format, type, 3, width, height, depth,
border )) { border )) {
if (level>=0 && level<ctx->Const.MaxTextureLevels) { if (level>=0 && level<ctx->Const.MaxTextureLevels) {
@@ -1250,7 +1241,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
else { else {
ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) format; ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) format;
set_teximage_component_sizes( ctx->Texture.Proxy3D->Image[level] ); 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]->Border = border;
ctx->Texture.Proxy3D->Image[level]->Width = width; ctx->Texture.Proxy3D->Image[level]->Width = width;
ctx->Texture.Proxy3D->Image[level]->Height = height; ctx->Texture.Proxy3D->Image[level]->Height = height;
@@ -1265,12 +1256,12 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
void void
_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, GLint border, GLenum format, GLenum type,
const GLvoid *pixels ) const GLvoid *pixels )
{ {
_mesa_TexImage3D(target, level, (GLint) internalformat, width, height, _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
depth, border, format, type, pixels); depth, border, format, type, pixels);
} }