package com.momega.spacesimulator.renderer;
import com.jogamp.common.nio.Buffers;
import com.momega.spacesimulator.model.Vector3d;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.swing.*;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.nio.ByteBuffer;
import java.util.List;
/**
* Superclass for all bitmap renderers
* Created by martin on 10/10/14.
*/
public abstract class AbstractBitmapRenderer extends AbstractRenderer {
private static final Logger logger = LoggerFactory.getLogger(AbstractBitmapRenderer.class);
private int imgHeight;
private int imgWidth;
private ByteBuffer imgRGBA;
public void init(GL2 gl) {
loadBitmap(getImageIcon());
}
/**
* Loads the bitmap. The method has to get the image and call {@link #loadBitmap(javax.swing.ImageIcon)}
*/
protected abstract ImageIcon getImageIcon();
public void draw(GLAutoDrawable drawable) {
List<Vector3d> positions = getPositions();
if (positions.isEmpty()) {
return;
}
GL2 gl = drawable.getGL().getGL2();
gl.glPushAttrib(GL2.GL_DEPTH_BUFFER_BIT);
gl.glPushAttrib(GL2.GL_COLOR_BUFFER_BIT);
{
//gl.glDisable(GL2.GL_DEPTH_TEST);
// enable alpha mask (import from gif sets alpha bits)
gl.glEnable(GL2.GL_BLEND);
gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
for(Vector3d pos : positions) {
gl.glRasterPos3dv(pos.asArray(), 0);
gl.glPixelZoom(1f, 1f); // x-factor, y-factor
gl.glBitmap(0, 0, 0, 0, -imgWidth / 2, -imgHeight / 2, null); // move the center of the bitmap
gl.glDrawPixels(imgWidth, imgHeight, GL2.GL_RGBA, GL.GL_UNSIGNED_BYTE, imgRGBA);
}
//gl.glEnable(GL2.GL_DEPTH_TEST);
}
gl.glPopAttrib();
gl.glPopAttrib();
}
public abstract List<Vector3d> getPositions();
protected void loadBitmap(ImageIcon icon) {
Image img = icon.getImage();
imgHeight = icon.getIconHeight();
imgWidth = icon.getIconWidth();
logger.debug("Image, width={} height={}" + imgWidth, imgHeight);
// Create a raster with correct size,
// and a colorModel and finally a bufImg.
//
WritableRaster raster =
Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
imgWidth,
imgHeight,
4,
null);
ComponentColorModel colorModel =
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[]{8, 8, 8, 8},
true,
false,
ComponentColorModel.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
BufferedImage bufImg =
new BufferedImage(colorModel, // color model
raster,
false, // isRasterPremultiplied
null); // properties
// Filter img into bufImg and perform
// Coordinate Transformations on the way.
//
Graphics2D g = bufImg.createGraphics();
AffineTransform gt = new AffineTransform();
gt.translate(0, imgHeight);
gt.scale(1, -1d);
g.transform(gt);
g.drawImage(img, null, null);
// Retrieve underlying byte array (imgBuf)
// from bufImg.
DataBufferByte imgBuf = (DataBufferByte) raster.getDataBuffer();
this.imgRGBA = Buffers.newDirectByteBuffer(imgBuf.getData());
//this.imgRGBA.flip();
if (g != null) {
g.dispose();
}
}
}