Optimized buffer allocation

This commit is contained in:
Ioannis Tsakpinis 2005-01-26 22:48:12 +00:00
parent a1fec2734a
commit d37c176cf4
1 changed files with 134 additions and 149 deletions

View File

@ -31,10 +31,10 @@
*/ */
package org.lwjgl.opengl.glu; package org.lwjgl.opengl.glu;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.nio.ByteBuffer;
/** /**
* MipMap.java * MipMap.java
@ -57,39 +57,24 @@ public class MipMap extends Util {
* @param data * @param data
* @return int * @return int
*/ */
public static int gluBuild2DMipmaps( public static int gluBuild2DMipmaps(final int target,
int target, final int components, final int width, final int height,
int components, final int format, final int type, final ByteBuffer data) {
int width,
int height,
int format,
int type,
ByteBuffer data) {
int retVal = 0;
int error;
int w, h, maxSize;
ByteBuffer image, newimage;
int neww, newh, level, bpp;
boolean done;
if ( width < 1 || height < 1 ) return GLU.GLU_INVALID_VALUE; if ( width < 1 || height < 1 ) return GLU.GLU_INVALID_VALUE;
maxSize = glGetIntegerv(GL11.GL_MAX_TEXTURE_SIZE); final int bpp = bytesPerPixel(format, type);
if ( bpp == 0 )
w = nearestPower(width);
if (w > maxSize) {
w = maxSize;
}
h = nearestPower(height);
if (h > maxSize) {
h = maxSize;
}
bpp = bytesPerPixel(format, type);
if (bpp == 0) {
return GLU.GLU_INVALID_ENUM; return GLU.GLU_INVALID_ENUM;
}
final int maxSize = glGetIntegerv(GL11.GL_MAX_TEXTURE_SIZE);
int w = nearestPower(width);
if ( w > maxSize )
w = maxSize;
int h = nearestPower(height);
if ( h > maxSize )
h = maxSize;
// Get current glPixelStore state // Get current glPixelStore state
PixelStoreState pss = new PixelStoreState(); PixelStoreState pss = new PixelStoreState();
@ -100,49 +85,62 @@ public class MipMap extends Util {
GL11.glPixelStorei(GL11.GL_PACK_SKIP_ROWS, 0); GL11.glPixelStorei(GL11.GL_PACK_SKIP_ROWS, 0);
GL11.glPixelStorei(GL11.GL_PACK_SKIP_PIXELS, 0); GL11.glPixelStorei(GL11.GL_PACK_SKIP_PIXELS, 0);
done = false; ByteBuffer image;
int retVal = 0;
boolean done = false;
if ( w != width || h != height ) { if ( w != width || h != height ) {
// must rescale image to get "top" mipmap texture image // must rescale image to get "top" mipmap texture image
image = BufferUtils.createByteBuffer((w + 4) * h * bpp); image = BufferUtils.createByteBuffer((w + 4) * h * bpp);
error = gluScaleImage(format, width, height, type, data, w, h, type, image); int error = gluScaleImage(format, width, height, type, data, w, h, type, image);
if ( error != 0 ) { if ( error != 0 ) {
retVal = error; retVal = error;
done = true; done = true;
} }
} else {
image = data;
}
level = 0;
while (!done) {
if (image != data) {
/* set pixel unpacking */ /* set pixel unpacking */
GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0); GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0); GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, 0);
GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0); GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, 0);
} else {
image = data;
} }
ByteBuffer bufferA = null;
ByteBuffer bufferB = null;
int level = 0;
while ( !done ) {
GL11.glTexImage2D(target, level, components, w, h, 0, format, type, image); GL11.glTexImage2D(target, level, components, w, h, 0, format, type, image);
if ( w == 1 && h == 1 ) if ( w == 1 && h == 1 )
break; break;
neww = (w < 2) ? 1 : w / 2; final int newW = (w < 2) ? 1 : w >> 1;
newh = (h < 2) ? 1 : h / 2; final int newH = (h < 2) ? 1 : h >> 1;
newimage = BufferUtils.createByteBuffer((neww + 4) * newh * bpp);
error = gluScaleImage(format, w, h, type, image, neww, newh, type, newimage); final ByteBuffer newImage;
if ( bufferA == null )
newImage = (bufferA = BufferUtils.createByteBuffer((newW + 4) * newH * bpp));
else if ( bufferB == null )
newImage = (bufferB = BufferUtils.createByteBuffer((newW + 4) * newH * bpp));
else
newImage = bufferB;
int error = gluScaleImage(format, w, h, type, image, newW, newH, type, newImage);
if ( error != 0 ) { if ( error != 0 ) {
retVal = error; retVal = error;
done = true; done = true;
} }
image = newimage; image = newImage;
if ( bufferB != null )
bufferB = bufferA;
w = neww; w = newW;
h = newh; h = newH;
level++; level++;
} }
@ -165,31 +163,23 @@ public class MipMap extends Util {
* @param dataOut * @param dataOut
* @return int * @return int
*/ */
public static int gluScaleImage( public static int gluScaleImage(int format,
int format, int widthIn, int heightIn, int typein, ByteBuffer dataIn,
int widthIn, int widthOut, int heightOut, int typeOut, ByteBuffer dataOut) {
int heightIn,
int typein,
ByteBuffer dataIn,
int widthOut,
int heightOut,
int typeOut,
ByteBuffer dataOut) {
int components, i, j, k; final int components = compPerPix(format);
float[] tempin, tempout; if ( components == -1 )
return GLU.GLU_INVALID_ENUM;
int i, j, k;
float[] tempIn, tempOut;
float sx, sy; float sx, sy;
int sizein, sizeout; int sizein, sizeout;
int rowstride, rowlen; int rowstride, rowlen;
components = compPerPix(format);
if (components == -1) {
return GLU.GLU_INVALID_ENUM;
}
// temp image data // temp image data
tempin = new float[widthIn * heightIn * components]; tempIn = new float[widthIn * heightIn * components];
tempout = new float[widthOut * heightOut * components]; tempOut = new float[widthOut * heightOut * components];
// Determine bytes per input type // Determine bytes per input type
switch ( typein ) { switch ( typein ) {
@ -205,7 +195,6 @@ public class MipMap extends Util {
case GL11.GL_UNSIGNED_BYTE: case GL11.GL_UNSIGNED_BYTE:
sizeout = 1; sizeout = 1;
break; break;
default: default:
return GL11.GL_INVALID_ENUM; return GL11.GL_INVALID_ENUM;
} }
@ -214,16 +203,15 @@ public class MipMap extends Util {
PixelStoreState pss = new PixelStoreState(); PixelStoreState pss = new PixelStoreState();
//Unpack the pixel data and convert to floating point //Unpack the pixel data and convert to floating point
if (pss.unpackRowLength > 0) { if ( pss.unpackRowLength > 0 )
rowlen = pss.unpackRowLength; rowlen = pss.unpackRowLength;
} else { else
rowlen = widthIn; rowlen = widthIn;
}
if (sizein >= pss.unpackAlignment) { if ( sizein >= pss.unpackAlignment )
rowstride = components * rowlen; rowstride = components * rowlen;
} else { else
rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment); rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment);
}
switch ( typein ) { switch ( typein ) {
case GL11.GL_UNSIGNED_BYTE: case GL11.GL_UNSIGNED_BYTE:
@ -232,11 +220,10 @@ public class MipMap extends Util {
for ( i = 0; i < heightIn; i++ ) { for ( i = 0; i < heightIn; i++ ) {
int ubptr = i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components; int ubptr = i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components;
for ( j = 0; j < widthIn * components; j++ ) { for ( j = 0; j < widthIn * components; j++ ) {
tempin[k++] = (float) ((int) dataIn.get(ubptr++) & 0xff); tempIn[k++] = (float)((int)dataIn.get(ubptr++) & 0xff);
} }
} }
break; break;
default: default:
return GLU.GLU_INVALID_ENUM; return GLU.GLU_INVALID_ENUM;
} }
@ -269,7 +256,7 @@ public class MipMap extends Util {
src = (iy0 * widthIn + ix0) * components; src = (iy0 * widthIn + ix0) * components;
for ( int ic = 0; ic < components; ic++ ) { for ( int ic = 0; ic < components; ic++ ) {
c[ic] += tempin[src + ic]; c[ic] += tempIn[src + ic];
} }
readPix++; readPix++;
@ -283,12 +270,12 @@ public class MipMap extends Util {
// Image is sized up, caused by non power of two texture as input // Image is sized up, caused by non power of two texture as input
src = (y0 * widthIn + x0) * components; src = (y0 * widthIn + x0) * components;
for ( int ic = 0; ic < components; ic++ ) { for ( int ic = 0; ic < components; ic++ ) {
tempout[dst++] = tempin[src + ic]; tempOut[dst++] = tempIn[src + ic];
} }
} else { } else {
// sized down // sized down
for ( k = 0; k < components; k++ ) { for ( k = 0; k < components; k++ ) {
tempout[dst++] = c[k] / readPix; tempOut[dst++] = c[k] / readPix;
} }
} }
} }
@ -296,16 +283,15 @@ public class MipMap extends Util {
// Convert temp output // Convert temp output
if (pss.packRowLength > 0) { if ( pss.packRowLength > 0 )
rowlen = pss.packRowLength; rowlen = pss.packRowLength;
} else { else
rowlen = widthOut; rowlen = widthOut;
}
if (sizeout >= pss.packAlignment) { if ( sizeout >= pss.packAlignment )
rowstride = components * rowlen; rowstride = components * rowlen;
} else { else
rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment); rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment);
}
switch ( typeOut ) { switch ( typeOut ) {
case GL11.GL_UNSIGNED_BYTE: case GL11.GL_UNSIGNED_BYTE:
@ -314,11 +300,10 @@ public class MipMap extends Util {
int ubptr = i * rowstride + pss.packSkipRows * rowstride + pss.packSkipPixels * components; int ubptr = i * rowstride + pss.packSkipRows * rowstride + pss.packSkipPixels * components;
for ( j = 0; j < widthOut * components; j++ ) { for ( j = 0; j < widthOut * components; j++ ) {
dataOut.put(ubptr++, (byte) tempout[k++]); dataOut.put(ubptr++, (byte)tempOut[k++]);
} }
} }
break; break;
default: default:
return GLU.GLU_INVALID_ENUM; return GLU.GLU_INVALID_ENUM;
} }