de.lessvoid.nifty.renderer.jogl.render.JoglRenderImage Maven / Gradle / Ivy
The newest version!
package de.lessvoid.nifty.renderer.jogl.render;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.glu.gl2.GLUgl2;
import de.lessvoid.nifty.render.io.ImageLoader;
import de.lessvoid.nifty.render.io.ImageLoaderFactory;
import de.lessvoid.nifty.spi.render.RenderImage;
import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
/**
* @author Julien Gouesse
*/
public class JoglRenderImage implements RenderImage {
@Nonnull
private final Logger log = Logger.getLogger(JoglRenderImage.class.getName());
@Nonnull
private final GLU glu;
private int width;
private int height;
private int textureWidth;
private int textureHeight;
private int textureId;
@Nonnull
public JoglRenderImage (
@Nonnull String filename,
final boolean filterParam,
@Nonnull final NiftyResourceLoader resourceLoader) {
log.fine("Loading image: " + filename);
ImageLoader loader = ImageLoaderFactory.createImageLoader(filename);
InputStream imageStream = null;
try {
imageStream = resourceLoader.getResourceAsStream(filename);
if (imageStream != null) {
ByteBuffer image = loader.loadAsByteBufferRGBA(imageStream);
image.rewind();
width = loader.getImageWidth();
height = loader.getImageHeight();
textureWidth = loader.getTextureWidth();
textureHeight = loader.getTextureHeight();
createTexture(image, textureWidth, textureHeight, filterParam ? GL.GL_LINEAR : GL.GL_NEAREST,
loader.getImageBitDepth() == 32 ? GL.GL_RGBA : GL.GL_RGB);
}
} catch (Exception e) {
log.log(Level.WARNING, "Could not load image from file: [" + filename + "]", e);
} finally {
if (imageStream != null) {
try {
imageStream.close();
} catch (IOException e) {
log.log(Level.INFO, "An error occurred while closing the InputStream used to load image: " + "[" + filename +
"].", e);
}
}
}
glu = new GLUgl2();//FIXME rather call GLU.createGLU(GLContext.getCurrentGL()); but ensure there is a current OpenGL context on this thread
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
public int getTextureWidth() {
return textureWidth;
}
public int getTextureHeight() {
return textureHeight;
}
@Override
public void dispose() {
}
private void createTexture(
final ByteBuffer textureBuffer, final int width, final int height,
final int filter, final int srcPixelFormat) throws Exception {
final GL gl = GLContext.getCurrentGL();
textureId = createTextureID();
bind();
int componentCount = 1;
IntBuffer temp = Buffers.newDirectIntBuffer(16);
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, temp);
checkGLError();
int max = temp.get(0);
if ((width > max) || (height > max)) {
throw new Exception("Attempt to allocate a texture to big for the current hardware");
}
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, filter);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, filter);
checkGLError();
if (filter == GL.GL_LINEAR_MIPMAP_NEAREST || filter == GL.GL_LINEAR_MIPMAP_LINEAR) {
glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D, componentCount, width, height, srcPixelFormat,
GL.GL_UNSIGNED_BYTE, textureBuffer);
} else {
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, width, height, 0, srcPixelFormat,
GL.GL_UNSIGNED_BYTE, textureBuffer);
}
checkGLError();
}
private int createTextureID() {
IntBuffer tmp = createIntBuffer(1);
final GL gl = GLContext.getCurrentGL();
gl.glGenTextures(1, tmp);
checkGLError();
return tmp.get(0);
}
@Nonnull
private IntBuffer createIntBuffer(final int size) {
ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
temp.order(ByteOrder.nativeOrder());
return temp.asIntBuffer();
}
public void bind() {
final GL gl = GLContext.getCurrentGL();
gl.glBindTexture(GL.GL_TEXTURE_2D, textureId);
checkGLError();
}
private void checkGLError() {
final GL gl = GLContext.getCurrentGL();
int error = gl.glGetError();
if (error != GL.GL_NO_ERROR) {
String glerrmsg = glu.gluErrorString(error);
log.warning("OpenGL Error: (" + error + ") " + glerrmsg);
}
}
}