use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.
the class KTXLoader method getImageFormat.
/**
* returns the JME image format from gl formats and types.
* @param glFormat
* @param glInternalFormat
* @param glType
* @return
*/
private Image.Format getImageFormat(int glFormat, int glInternalFormat, int glType) {
EnumSet<Caps> caps = EnumSet.allOf(Caps.class);
GLImageFormat[][] formats = GLImageFormats.getFormatsForCaps(caps);
for (GLImageFormat[] format : formats) {
for (int j = 0; j < format.length; j++) {
GLImageFormat glImgFormat = format[j];
if (glImgFormat != null) {
if (glImgFormat.format == glFormat && glImgFormat.dataType == glType) {
if (glFormat == glInternalFormat || glImgFormat.internalFormat == glInternalFormat) {
return Image.Format.values()[j];
}
}
}
}
}
return null;
}
use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.
the class TextureUtil method uploadTexture.
public void uploadTexture(Image image, int target, int index, boolean linearizeSrgb) {
boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
Image.Format jmeFormat = image.getFormat();
GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
ByteBuffer data = null;
int sliceCount = 1;
if (index >= 0) {
data = image.getData(index);
}
if (image.getData() != null && image.getData().size() > 0) {
sliceCount = image.getData().size();
}
int width = image.getWidth();
int height = image.getHeight();
int depth = image.getDepth();
int[] mipSizes = image.getMipMapSizes();
int pos = 0;
// TODO: Remove unneccessary allocation
if (mipSizes == null) {
if (data != null) {
mipSizes = new int[] { data.capacity() };
} else {
mipSizes = new int[] { width * height * jmeFormat.getBitsPerPixel() / 8 };
}
}
int samples = image.getMultiSamples();
// For OGL3 core: setup texture swizzle.
if (oglFormat.swizzleRequired) {
setupTextureSwizzle(target, jmeFormat);
}
for (int i = 0; i < mipSizes.length; i++) {
int mipWidth = Math.max(1, width >> i);
int mipHeight = Math.max(1, height >> i);
int mipDepth = Math.max(1, depth >> i);
if (data != null) {
data.position(pos);
data.limit(pos + mipSizes[i]);
}
uploadTextureLevel(oglFormat, target, i, index, sliceCount, mipWidth, mipHeight, mipDepth, samples, data);
pos += mipSizes[i];
}
}
use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.
the class TextureUtil method uploadSubTexture.
public void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) {
throw new UnsupportedOperationException("Updating non-2D texture is not supported");
}
if (image.getMipMapSizes() != null) {
throw new UnsupportedOperationException("Updating mip-mappped images is not supported");
}
if (image.getMultiSamples() > 1) {
throw new UnsupportedOperationException("Updating multisampled images is not supported");
}
Image.Format jmeFormat = image.getFormat();
if (jmeFormat.isCompressed()) {
throw new UnsupportedOperationException("Updating compressed images is not supported");
} else if (jmeFormat.isDepthFormat()) {
throw new UnsupportedOperationException("Updating depth images is not supported");
}
boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
ByteBuffer data = null;
if (index >= 0) {
data = image.getData(index);
}
if (data == null) {
throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
}
data.position(0);
data.limit(data.capacity());
gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(), oglFormat.format, oglFormat.dataType, data);
}
use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.
the class TextureUtil method uploadSubTexture.
/**
* Update the texture currently bound to target at with data from the given Image at position x and y. The parameter
* index is used as the zoffset in case a 3d texture or texture 2d array is being updated.
*
* @param image Image with the source data (this data will be put into the texture)
* @param target the target texture
* @param index the mipmap level to update
* @param x the x position where to put the image in the texture
* @param y the y position where to put the image in the texture
*/
public static void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
GL gl = GLContext.getCurrentGL();
Image.Format fmt = image.getFormat();
GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
ByteBuffer data = null;
if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
data = image.getData(index);
}
int width = image.getWidth();
int height = image.getHeight();
int depth = image.getDepth();
if (data != null) {
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
}
int[] mipSizes = image.getMipMapSizes();
int pos = 0;
// TODO: Remove unneccessary allocation
if (mipSizes == null) {
if (data != null) {
mipSizes = new int[] { data.capacity() };
} else {
mipSizes = new int[] { width * height * fmt.getBitsPerPixel() / 8 };
}
}
int samples = image.getMultiSamples();
for (int i = 0; i < mipSizes.length; i++) {
int mipWidth = Math.max(1, width >> i);
int mipHeight = Math.max(1, height >> i);
int mipDepth = Math.max(1, depth >> i);
if (data != null) {
data.position(pos);
data.limit(pos + mipSizes[i]);
}
// to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
// gl*Image call in an attempt to unclutter things a bit
pos += mipSizes[i];
int glFmtInternal = glFmt.internalFormat;
int glFmtFormat = glFmt.format;
int glFmtDataType = glFmt.dataType;
if (glFmt.compressed && data != null) {
if (target == GL2ES2.GL_TEXTURE_3D) {
gl.getGL2ES2().glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data.limit(), data);
continue;
}
// all other targets use 2D: array, cubemap, 2d
gl.getGL2ES2().glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data.limit(), data);
continue;
}
if (target == GL2ES2.GL_TEXTURE_3D) {
gl.getGL2ES2().glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
continue;
}
if (samples > 1) {
throw new IllegalStateException("Cannot update multisample textures");
}
gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
continue;
}
}
use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.
the class KTXWriter method write.
/**
* Writes an image with the given params
*
* textureType, allows one to write textureArrays, Texture3D, and TextureCubeMaps.
* Texture2D will write a 2D image.
* Note that the fileName should contain the extension (.ktx sounds like a wise choice)
* @param image the image to write
* @param textureType the texture type
* @param fileName the name of the file to write
*/
public void write(Image image, Class<? extends Texture> textureType, String fileName) {
FileOutputStream outs = null;
try {
File file = new File(filePath + "/" + fileName);
outs = new FileOutputStream(file);
DataOutput out = new DataOutputStream(outs);
//fileID
out.write(fileIdentifier);
//endianness
out.writeInt(0x04030201);
GLImageFormat format = getGlFormat(image.getFormat());
//glType
out.writeInt(format.dataType);
//glTypeSize
out.writeInt(1);
//glFormat
out.writeInt(format.format);
//glInernalFormat
out.writeInt(format.internalFormat);
//glBaseInternalFormat
out.writeInt(format.format);
//pixelWidth
out.writeInt(image.getWidth());
//pixelHeight
out.writeInt(image.getHeight());
int pixelDepth = 1;
int numberOfArrayElements = 1;
int numberOfFaces = 1;
if (image.getDepth() > 1) {
//pixelDepth
if (textureType == Texture3D.class) {
pixelDepth = image.getDepth();
}
}
if (image.getData().size() > 1) {
//numberOfArrayElements
if (textureType == TextureArray.class) {
numberOfArrayElements = image.getData().size();
}
//numberOfFaces
if (textureType == TextureCubeMap.class) {
numberOfFaces = image.getData().size();
}
}
out.writeInt(pixelDepth);
out.writeInt(numberOfArrayElements);
out.writeInt(numberOfFaces);
int numberOfMipmapLevels = 1;
//numberOfMipmapLevels
if (image.hasMipmaps()) {
numberOfMipmapLevels = image.getMipMapSizes().length;
}
out.writeInt(numberOfMipmapLevels);
//bytesOfKeyValueData
String keyValues = "KTXorientation\0S=r,T=u\0";
int bytesOfKeyValueData = keyValues.length() + 4;
int padding = 3 - ((bytesOfKeyValueData + 3) % 4);
bytesOfKeyValueData += padding;
out.writeInt(bytesOfKeyValueData);
//keyAndValueByteSize
out.writeInt(bytesOfKeyValueData - 4 - padding);
//values
out.writeBytes(keyValues);
pad(padding, out);
int offset = 0;
//iterate over data
for (int mipLevel = 0; mipLevel < numberOfMipmapLevels; mipLevel++) {
int width = Math.max(1, image.getWidth() >> mipLevel);
int height = Math.max(1, image.getHeight() >> mipLevel);
int imageSize;
if (image.hasMipmaps()) {
imageSize = image.getMipMapSizes()[mipLevel];
} else {
imageSize = width * height * image.getFormat().getBitsPerPixel() / 8;
}
out.writeInt(imageSize);
for (int arrayElem = 0; arrayElem < numberOfArrayElements; arrayElem++) {
for (int face = 0; face < numberOfFaces; face++) {
int nbPixelWritten = 0;
for (int depth = 0; depth < pixelDepth; depth++) {
ByteBuffer byteBuffer = image.getData(getSlice(face, arrayElem));
// BufferUtils.ensureLargeEnough(byteBuffer, imageSize);
log.log(Level.FINE, "position {0}", byteBuffer.position());
byteBuffer.position(offset);
byte[] b = getByteBufferArray(byteBuffer, imageSize);
out.write(b);
nbPixelWritten = b.length;
}
//cube padding
if (numberOfFaces == 6 && numberOfArrayElements == 0) {
padding = 3 - ((nbPixelWritten + 3) % 4);
pad(padding, out);
}
}
}
//mip padding
log.log(Level.FINE, "skipping {0}", (3 - ((imageSize + 3) % 4)));
padding = 3 - ((imageSize + 3) % 4);
pad(padding, out);
offset += imageSize;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (outs != null) {
outs.close();
}
} catch (IOException ex) {
Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Aggregations