Optimized buffer allocation
This commit is contained in:
parent
a1fec2734a
commit
d37c176cf4
|
@ -1,40 +1,40 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) 2002-2004 LWJGL Project
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'LWJGL' nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* * Neither the name of 'LWJGL' nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.lwjgl.opengl.glu;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* MipMap.java
|
||||
|
@ -57,39 +57,24 @@ public class MipMap extends Util {
|
|||
* @param data
|
||||
* @return int
|
||||
*/
|
||||
public static int gluBuild2DMipmaps(
|
||||
int target,
|
||||
int components,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int type,
|
||||
ByteBuffer data) {
|
||||
public static int gluBuild2DMipmaps(final int target,
|
||||
final int components, final int width, final int height,
|
||||
final int format, final int type, final ByteBuffer data) {
|
||||
if ( width < 1 || height < 1 ) return GLU.GLU_INVALID_VALUE;
|
||||
|
||||
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;
|
||||
|
||||
maxSize = glGetIntegerv(GL11.GL_MAX_TEXTURE_SIZE);
|
||||
|
||||
w = nearestPower(width);
|
||||
if (w > maxSize) {
|
||||
w = maxSize;
|
||||
}
|
||||
h = nearestPower(height);
|
||||
if (h > maxSize) {
|
||||
h = maxSize;
|
||||
}
|
||||
|
||||
bpp = bytesPerPixel(format, type);
|
||||
if (bpp == 0) {
|
||||
final int bpp = bytesPerPixel(format, type);
|
||||
if ( bpp == 0 )
|
||||
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
|
||||
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_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
|
||||
image = BufferUtils.createByteBuffer((w + 4) * h * bpp);
|
||||
error = gluScaleImage(format, width, height, type, data, w, h, type, image);
|
||||
if (error != 0) {
|
||||
int error = gluScaleImage(format, width, height, type, data, w, h, type, image);
|
||||
if ( error != 0 ) {
|
||||
retVal = error;
|
||||
done = true;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
} else {
|
||||
image = data;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
ByteBuffer bufferA = null;
|
||||
ByteBuffer bufferB = null;
|
||||
|
||||
int level = 0;
|
||||
while ( !done ) {
|
||||
GL11.glTexImage2D(target, level, components, w, h, 0, format, type, image);
|
||||
|
||||
if (w == 1 && h == 1)
|
||||
if ( w == 1 && h == 1 )
|
||||
break;
|
||||
|
||||
neww = (w < 2) ? 1 : w / 2;
|
||||
newh = (h < 2) ? 1 : h / 2;
|
||||
newimage = BufferUtils.createByteBuffer((neww + 4) * newh * bpp);
|
||||
final int newW = (w < 2) ? 1 : w >> 1;
|
||||
final int newH = (h < 2) ? 1 : h >> 1;
|
||||
|
||||
error = gluScaleImage(format, w, h, type, image, neww, newh, type, newimage);
|
||||
if (error != 0) {
|
||||
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 ) {
|
||||
retVal = error;
|
||||
done = true;
|
||||
}
|
||||
|
||||
image = newimage;
|
||||
image = newImage;
|
||||
if ( bufferB != null )
|
||||
bufferB = bufferA;
|
||||
|
||||
w = neww;
|
||||
h = newh;
|
||||
w = newW;
|
||||
h = newH;
|
||||
level++;
|
||||
}
|
||||
|
||||
|
@ -165,48 +163,39 @@ public class MipMap extends Util {
|
|||
* @param dataOut
|
||||
* @return int
|
||||
*/
|
||||
public static int gluScaleImage(
|
||||
int format,
|
||||
int widthIn,
|
||||
int heightIn,
|
||||
int typein,
|
||||
ByteBuffer dataIn,
|
||||
int widthOut,
|
||||
int heightOut,
|
||||
int typeOut,
|
||||
ByteBuffer dataOut) {
|
||||
public static int gluScaleImage(int format,
|
||||
int widthIn, int heightIn, int typein, ByteBuffer dataIn,
|
||||
int widthOut, int heightOut, int typeOut, ByteBuffer dataOut) {
|
||||
|
||||
int components, i, j, k;
|
||||
float[] tempin, tempout;
|
||||
final int components = compPerPix(format);
|
||||
if ( components == -1 )
|
||||
return GLU.GLU_INVALID_ENUM;
|
||||
|
||||
int i, j, k;
|
||||
float[] tempIn, tempOut;
|
||||
float sx, sy;
|
||||
int sizein, sizeout;
|
||||
int rowstride, rowlen;
|
||||
|
||||
components = compPerPix(format);
|
||||
if (components == -1) {
|
||||
return GLU.GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
// temp image data
|
||||
tempin = new float[widthIn * heightIn * components];
|
||||
tempout = new float[widthOut * heightOut * components];
|
||||
tempIn = new float[widthIn * heightIn * components];
|
||||
tempOut = new float[widthOut * heightOut * components];
|
||||
|
||||
// Determine bytes per input type
|
||||
switch (typein) {
|
||||
case GL11.GL_UNSIGNED_BYTE :
|
||||
switch ( typein ) {
|
||||
case GL11.GL_UNSIGNED_BYTE:
|
||||
sizein = 1;
|
||||
break;
|
||||
default :
|
||||
default:
|
||||
return GL11.GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
// Determine bytes per output type
|
||||
switch (typeOut) {
|
||||
case GL11.GL_UNSIGNED_BYTE :
|
||||
switch ( typeOut ) {
|
||||
case GL11.GL_UNSIGNED_BYTE:
|
||||
sizeout = 1;
|
||||
break;
|
||||
|
||||
default :
|
||||
default:
|
||||
return GL11.GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
|
@ -214,62 +203,60 @@ public class MipMap extends Util {
|
|||
PixelStoreState pss = new PixelStoreState();
|
||||
|
||||
//Unpack the pixel data and convert to floating point
|
||||
if (pss.unpackRowLength > 0) {
|
||||
if ( pss.unpackRowLength > 0 )
|
||||
rowlen = pss.unpackRowLength;
|
||||
} else {
|
||||
else
|
||||
rowlen = widthIn;
|
||||
}
|
||||
if (sizein >= pss.unpackAlignment) {
|
||||
rowstride = components * rowlen;
|
||||
} else {
|
||||
rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment);
|
||||
}
|
||||
|
||||
switch (typein) {
|
||||
case GL11.GL_UNSIGNED_BYTE :
|
||||
if ( sizein >= pss.unpackAlignment )
|
||||
rowstride = components * rowlen;
|
||||
else
|
||||
rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment);
|
||||
|
||||
switch ( typein ) {
|
||||
case GL11.GL_UNSIGNED_BYTE:
|
||||
k = 0;
|
||||
dataIn.rewind();
|
||||
for (i = 0; i < heightIn; i++) {
|
||||
for ( i = 0; i < heightIn; i++ ) {
|
||||
int ubptr = i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components;
|
||||
for (j = 0; j < widthIn * components; j++) {
|
||||
tempin[k++] = (float) ((int) dataIn.get(ubptr++) & 0xff);
|
||||
for ( j = 0; j < widthIn * components; j++ ) {
|
||||
tempIn[k++] = (float)((int)dataIn.get(ubptr++) & 0xff);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
default:
|
||||
return GLU.GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
// Do scaling
|
||||
sx = (float) widthIn / (float) widthOut;
|
||||
sy = (float) heightIn / (float) heightOut;
|
||||
sx = (float)widthIn / (float)widthOut;
|
||||
sy = (float)heightIn / (float)heightOut;
|
||||
|
||||
float[] c = new float[components];
|
||||
int src, dst;
|
||||
|
||||
for (int iy = 0; iy < heightOut; iy++) {
|
||||
for (int ix = 0; ix < widthOut; ix++) {
|
||||
int x0 = (int) (ix * sx);
|
||||
int x1 = (int) ((ix + 1) * sx);
|
||||
int y0 = (int) (iy * sy);
|
||||
int y1 = (int) ((iy + 1) * sy);
|
||||
for ( int iy = 0; iy < heightOut; iy++ ) {
|
||||
for ( int ix = 0; ix < widthOut; ix++ ) {
|
||||
int x0 = (int)(ix * sx);
|
||||
int x1 = (int)((ix + 1) * sx);
|
||||
int y0 = (int)(iy * sy);
|
||||
int y1 = (int)((iy + 1) * sy);
|
||||
|
||||
int readPix = 0;
|
||||
|
||||
// reset weighted pixel
|
||||
for (int ic = 0; ic < components; ic++) {
|
||||
for ( int ic = 0; ic < components; ic++ ) {
|
||||
c[ic] = 0;
|
||||
}
|
||||
|
||||
// create weighted pixel
|
||||
for (int ix0 = x0; ix0 < x1; ix0++) {
|
||||
for (int iy0 = y0; iy0 < y1; iy0++) {
|
||||
for ( int ix0 = x0; ix0 < x1; ix0++ ) {
|
||||
for ( int iy0 = y0; iy0 < y1; iy0++ ) {
|
||||
|
||||
src = (iy0 * widthIn + ix0) * components;
|
||||
|
||||
for (int ic = 0; ic < components; ic++) {
|
||||
c[ic] += tempin[src + ic];
|
||||
for ( int ic = 0; ic < components; ic++ ) {
|
||||
c[ic] += tempIn[src + ic];
|
||||
}
|
||||
|
||||
readPix++;
|
||||
|
@ -279,47 +266,45 @@ public class MipMap extends Util {
|
|||
// store weighted pixel
|
||||
dst = (iy * widthOut + ix) * components;
|
||||
|
||||
if (readPix == 0) {
|
||||
// Image is sized up, caused by non power of two texture as input
|
||||
src = (y0 * widthIn + x0) * components;
|
||||
for (int ic = 0; ic < components; ic++) {
|
||||
tempout[dst++] = tempin[src + ic];
|
||||
}
|
||||
if ( readPix == 0 ) {
|
||||
// Image is sized up, caused by non power of two texture as input
|
||||
src = (y0 * widthIn + x0) * components;
|
||||
for ( int ic = 0; ic < components; ic++ ) {
|
||||
tempOut[dst++] = tempIn[src + ic];
|
||||
}
|
||||
} else {
|
||||
// sized down
|
||||
for (k = 0; k < components; k++) {
|
||||
tempout[dst++] = c[k] / readPix;
|
||||
}
|
||||
}
|
||||
// sized down
|
||||
for ( k = 0; k < components; k++ ) {
|
||||
tempOut[dst++] = c[k] / readPix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convert temp output
|
||||
if (pss.packRowLength > 0) {
|
||||
if ( pss.packRowLength > 0 )
|
||||
rowlen = pss.packRowLength;
|
||||
} else {
|
||||
else
|
||||
rowlen = widthOut;
|
||||
}
|
||||
if (sizeout >= pss.packAlignment) {
|
||||
rowstride = components * rowlen;
|
||||
} else {
|
||||
rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment);
|
||||
}
|
||||
|
||||
switch (typeOut) {
|
||||
case GL11.GL_UNSIGNED_BYTE :
|
||||
if ( sizeout >= pss.packAlignment )
|
||||
rowstride = components * rowlen;
|
||||
else
|
||||
rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment);
|
||||
|
||||
switch ( typeOut ) {
|
||||
case GL11.GL_UNSIGNED_BYTE:
|
||||
k = 0;
|
||||
for (i = 0; i < heightOut; i++) {
|
||||
for ( i = 0; i < heightOut; i++ ) {
|
||||
int ubptr = i * rowstride + pss.packSkipRows * rowstride + pss.packSkipPixels * components;
|
||||
|
||||
for (j = 0; j < widthOut * components; j++) {
|
||||
dataOut.put(ubptr++, (byte) tempout[k++]);
|
||||
for ( j = 0; j < widthOut * components; j++ ) {
|
||||
dataOut.put(ubptr++, (byte)tempOut[k++]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
default:
|
||||
return GLU.GLU_INVALID_ENUM;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue