gluBuild2DMipMap - pixel alignment bug in 0.97

Started by tb, May 26, 2005, 11:16:19

Previous topic - Next topic

tb

The default pack/unpacck alignemnt of opengl is 4/4. In your gluBuild2DMipMap it is set to 1/4 which results into incorret mip maps. It looks like the code was converted faulty(missing pointer comparison in the while loop) from the mesa lib (mipmap.c). Simply insert a second   gl11.glpixelstorei(gl11.gl_unpack...) block under the first "image = newImage" in the while loop."

Thomas

Matzon

pardon my ignorance, but shouldn't the use of PixelStoreState load/save be enough ?

tb

nope, because the methode looks like this:

// Get current glPixelStore state
       PixelStoreState pss = new PixelStoreState();

       // set pixel packing
       GL11.glPixelStorei(GL11.GL_PACK_ROW_LENGTH, 0);
       GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
       GL11.glPixelStorei(GL11.GL_PACK_SKIP_ROWS, 0);
       GL11.glPixelStorei(GL11.GL_PACK_SKIP_PIXELS, 0);

// image scaling code
// which goes wrong if pack and unpack alignment are different....

// Restore original glPixelStore state
       pss.save();

Thomas

P.S. original  MESA code, which does it right:

GLint GLAPIENTRY
gluBuild2DMipmaps(GLenum target, GLint components,
		  GLsizei width, GLsizei height, GLenum format,
		  GLenum type, const void *data)
{
   GLint w, h, maxsize;
   void *image, *newimage;
   GLint neww, newh, level, bpp;
   int error;
   GLboolean done;
   GLint retval = 0;
   GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
   GLint packrowlength, packalignment, packskiprows, packskippixels;

   if (width < 1 || height < 1)
      return GLU_INVALID_VALUE;

   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);

   w = round2(width);
   if (w > maxsize) {
      w = maxsize;
   }
   h = round2(height);
   if (h > maxsize) {
      h = maxsize;
   }

   bpp = bytes_per_pixel(format, type);
   if (bpp == 0) {
      /* probably a bad format or type enum */
      return GLU_INVALID_ENUM;
   }

   /* Get current glPixelStore values */
   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
   glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
   glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
   glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
   glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
   glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);

   /* set pixel packing */
   glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
   glPixelStorei(GL_PACK_SKIP_ROWS, 0);
   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

   done = GL_FALSE;

   if (w != width || h != height) {
      /* must rescale image to get "top" mipmap texture image */
      image = malloc((w + 4) * h * bpp);
      if (!image) {
	 return GLU_OUT_OF_MEMORY;
      }
      error = gluScaleImage(format, width, height, type, data,
			    w, h, type, image);
      if (error) {
	 retval = error;
	 done = GL_TRUE;
      }
   }
   else {
      image = (void *) data;
   }

   level = 0;
   while (!done) {
      if (image != data) { // here is the error in the lwjgl!!!!
	 /* set pixel unpacking */
	 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
	 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
      }

      glTexImage2D(target, level, components, w, h, 0, format, type, image);

      if (w == 1 && h == 1)
	 break;

      neww = (w < 2) ? 1 : w / 2;
      newh = (h < 2) ? 1 : h / 2;
      newimage = malloc((neww + 4) * newh * bpp);
      if (!newimage) {
	 return GLU_OUT_OF_MEMORY;
      }

      error = gluScaleImage(format, w, h, type, image,
			    neww, newh, type, newimage);
      if (error) {
	 retval = error;
	 done = GL_TRUE;
      }

      if (image != data) {
	 free(image);
      }
      image = newimage;

      w = neww;
      h = newh;
      level++;
   }

   if (image != data) {
      free(image);
   }

   /* Restore original glPixelStore state */
   glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
   glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
   glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
   glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
   glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
   glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
   glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);

   return retval;
}

Matzon

comitted to cvs:
QuoteIndex: MipMap.java
===================================================================
RCS file: /cvsroot/java-game-lib/LWJGL/src/java/org/lwjgl/opengl/glu/MipMap.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- MipMap.java   28 May 2005 08:48:01 -0000   1.10
+++ MipMap.java   16 Jun 2005 11:18:44 -0000   1.11
@@ -112,6 +112,14 @@

      int level = 0;
      while ( !done ) {
+         if (image != data) {
+            /* set pixel unpacking */
+            GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0);
+            GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
+            GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0);
+            GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0);
+         }          
+         
         GL11.glTexImage2D(target, level, components, w, h, 0, format, type, image);

         if ( w == 1 && h == 1 )