Optimized buffer allocation
This commit is contained in:
parent
a1fec2734a
commit
d37c176cf4
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue