LWJGL Forum

Programming => OpenGL => Topic started by: tb on May 26, 2005, 11:16:19

Title: gluBuild2DMipMap - pixel alignment bug in 0.97
Post by: tb on May 26, 2005, 11:16:19
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
Title: gluBuild2DMipMap - pixel alignment bug in 0.97
Post by: Matzon on May 28, 2005, 08:59:07
pardon my ignorance, but shouldn't the use of PixelStoreState load/save be enough ?
Title: gluBuild2DMipMap - pixel alignment bug in 0.97
Post by: tb on May 28, 2005, 15:02:59
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;
}
Title: gluBuild2DMipMap - pixel alignment bug in 0.97
Post by: Matzon on June 16, 2005, 11:24:24
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 )