package teamcomm.gui.drawings;
import com.jogamp.opengl.GL2;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.charset.Charset;
import javax.swing.JOptionPane;
import teamcomm.gui.drawings.TextureLoader.Texture;
/**
* Helper class for drawing text.
*
* @author Felix Thielke
*/
public class Text {
private static final int CHAR_WIDTH_PX = 42;
private static final int CHAR_HEIGHT_PX = 82;
private static final double CHAR_PX_RATIO = (double) CHAR_WIDTH_PX / (double) CHAR_HEIGHT_PX;
/**
* Draw the given text at the given position. Only characters in the ASCII
* charset are allowed, others are ignored.
*
* @param gl OpenGL context
* @param text text to draw
* @param centerX center X coordinate at which the text is drawn
* @param centerY center Y coordinate at which the text is drawn
* @param size height of the font
*/
public static void drawText(final GL2 gl, final String text, final float centerX, final float centerY, final float size) {
drawText(gl, text, centerX, centerY, size, new float[]{1, 1, 1, 1});
}
/**
* Draw the given text at the given position. Only characters in the ASCII
* charset are allowed, others are ignored.
*
* @param gl OpenGL context
* @param text text to draw
* @param centerX center X coordinate at which the text is drawn
* @param centerY center Y coordinate at which the text is drawn
* @param size height of the font
* @param color array with rgb or rgba values describing the color of the
* text (color values are in the range [0.0f,1.0f])
*/
public static void drawText(final GL2 gl, final String text, final float centerX, final float centerY, final float size, final float[] color) {
final FloatBuffer colorBuffer;
if (color.length > 4) {
return;
} else if (color.length < 4) {
colorBuffer = FloatBuffer.allocate(4);
for (final float c : color) {
colorBuffer.put(c);
}
while (colorBuffer.position() < 4) {
colorBuffer.put(1);
}
} else {
colorBuffer = FloatBuffer.wrap(color);
}
// Load texture
final Texture tex;
try {
tex = TextureLoader.getInstance().loadTexture(gl, new File("scene/Textures/ascii.png"));
} catch (IOException ex) {
// Handle error
JOptionPane.showMessageDialog(null,
"Error loading texture",
"IOException",
JOptionPane.ERROR_MESSAGE);
return;
}
// Set material
gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_AMBIENT_AND_DIFFUSE);
gl.glColor4fv(colorBuffer);
gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, FloatBuffer.wrap(new float[]{0.0f, 0.0f, 0.0f, 1.0f}));
gl.glMaterialf(GL2.GL_FRONT, GL2.GL_SHININESS, 0.0f);
gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_EMISSION, FloatBuffer.wrap(new float[]{0.0f, 0.0f, 0.0f, 1.0f}));
gl.glBindTexture(GL2.GL_TEXTURE_2D, tex.id);
if (tex.hasAlpha) {
gl.glEnable(GL2.GL_BLEND);
gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
}
final float charWidth = (float) ((double) size * CHAR_PX_RATIO);
final float[] startOffset = new float[]{centerX - (text.length() * charWidth) / 2, centerY + size / 2};
int n = 0;
gl.glBegin(GL2.GL_QUADS);
for (final byte b : text.getBytes(Charset.forName("ASCII"))) {
if (b < 0x20 || b >= (0x20 + 95)) {
continue;
}
final float[] texCoordsX = new float[]{(float) (b - 0x20) / 95.0f, (float) (b - 0x1F) / 95.0f};
gl.glTexCoord2f(texCoordsX[0], 0);
gl.glNormal3f(0, 0, 1);
gl.glVertex3f(startOffset[0] + (float) n * charWidth, startOffset[1], 0);
gl.glTexCoord2f(texCoordsX[0], 1);
gl.glNormal3f(0, 0, 1);
gl.glVertex3f(startOffset[0] + (float) n * charWidth, startOffset[1] - size, 0);
gl.glTexCoord2f(texCoordsX[1], 1);
gl.glNormal3f(0, 0, 1);
gl.glVertex3f(startOffset[0] + (float) (n + 1) * charWidth, startOffset[1] - size, 0);
gl.glTexCoord2f(texCoordsX[1], 0);
gl.glNormal3f(0, 0, 1);
gl.glVertex3f(startOffset[0] + (float) (n + 1) * charWidth, startOffset[1], 0);
n++;
}
gl.glEnd();
// Unset material
gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
if (tex.hasAlpha) {
gl.glDisable(GL2.GL_BLEND);
}
}
}