📄 glf.java
字号:
package demos.nehe.lesson15;
import demos.common.LittleEndianDataInputStream;
import javax.media.opengl.GL;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
/**
* GLF Library
* Version 1.4
*
* Author: Roman Podobedov
* Email: romka@ut.ee
* WEB: http://romka.demonews.com
* Release Date: 18 May 2001
*
* Copyright (C) 2000-2001, Romka Graphics
* This library is freely distributable without any license or permissions
* for non-commercial usage. You can use this library in any non-commercial
* program. In each program, where you use this library you should keep
* this header (author name and coordinates)!
* For commercial usage, please contact me: romka@ut.ee
*
* @author Pepijn Van Eeckhoudt
*/
public class GLF {
private static final int MAX_FONTS = 256;
// private static final int SEEK_SET_POS = 4195;
public static final int GLF_ERROR = -1;
public static final int GLF_OK = 0;
public static final int GLF_YES = 1;
public static final int GLF_NO = 2;
public static final int GLF_CONSOLE_MESSAGES = 10;
public static final int GLF_TEXTURING = 11;
public static final int GLF_CONTOURING = 12;
public static final int GLF_LEFT_UP = 20;
public static final int GLF_LEFT_CENTER = 21;
public static final int GLF_LEFT_DOWN = 22;
public static final int GLF_CENTER_UP = 23;
public static final int GLF_CENTER = 24;
public static final int GLF_CENTER_CENTER = 24;
public static final int GLF_CENTER_DOWN = 25;
public static final int GLF_RIGHT_UP = 26;
public static final int GLF_RIGHT_CENTER = 27;
public static final int GLF_RIGHT_DOWN = 28;
public static final int GLF_LEFT = 1;
public static final int GLF_RIGHT = 2;
public static final int GLF_UP = 3;
public static final int GLF_DOWN = 4;
public static final int GLF_CONSOLE_CURSOR = 30;
/* ------------- Main variables -------------- */
private int refNumber = 0;
private float SymbolDist = 0.2f; /* Distance between symbols (Variable constant) */
private float SymbolDepth = 0.2f; /* Symbol Depth in 3D space (Variable constant) */
private float SpaceSize = 2.0f; /* Space size (Variable constant) */
private float RotateAngle = 0.0f; /* Rotate angle for string (vector font) */
// private float RotateAngleB = 0.0f; /* Rotate angle for string (bitmap font) */
/* Array of font pointers, up to MAX_FONTS fonts can be loaded at once */
/* if (fonts[i] == NULL) then this font is not present in memory */
private GLFFont[] fonts = new GLFFont[MAX_FONTS];
private int curfont; /* Index of current font pointer */
private int ap = GLF_CENTER; /* Anchor point */
private boolean m_string_center; /* String centering (vector fonts) */
// private boolean m_bitmap_string_center; /* String centering (bitmap fonts) */
private int m_direction; /* String direction (vector fonts) */
private char console_msg = GLF_NO;
private char texturing = GLF_NO;
private char contouring = GLF_NO;
private float[] contouring_color;
/* Console mode variables */
private int conWidth, conHeight; /* Console width and height */
private int conx = 0, cony = 0; /* Console current X and Y */
private StringBuffer[] conData; /* Console data */
private int conFont; /* Console font */
private char conCursor = GLF_NO; /* Console cursor Enabled|Disabled */
private int conCursorBlink; /* Console cursor blink rate */
private int conCursorCount; /* Console cursor blink counter */
private char conCursorMode = GLF_NO; /* Console Cursor mode (on/off screen) */
/* ----------- Variables for bitmap font ------------- */
private static class coord_rect {
float x, y, width, height;
};
private static class widths {
float[] width;
};
/* Constants */
private float sym_space = 0.001f;
/* One font variables */
private coord_rect[] Symbols;
private boolean bmf_texturing;
private int bmf_curfont;
private int[] bmf_texture = new int[MAX_FONTS]; /* All fonts */
private int[] bmf_mask = new int[MAX_FONTS]; /* All fonts (masked) */
private boolean[] bmf_in_use = new boolean[MAX_FONTS]; /* 1 - if font is used, 0 - otherwise */
private int[] list_base = new int[MAX_FONTS];
private float[] m_max_height = new float[MAX_FONTS]; /* Maximal height of each font */
private widths[] m_widths = new widths[MAX_FONTS]; /* Width of each symbols in each font */
private static interface DrawSymbol {
void drawCharacter(GL gl, char s);
}
private DrawSymbol drawWiredSymbol = new DrawSymbol() {
public void drawCharacter(GL gl, char s) {
glfDrawWiredSymbol(gl, s);
}
};
private DrawSymbol draw3DWiredSymbol = new DrawSymbol() {
public void drawCharacter(GL gl, char s) {
glfDraw3DWiredSymbol(gl, s);
}
};
private DrawSymbol drawSolidSymbol = new DrawSymbol() {
public void drawCharacter(GL gl, char s) {
glfDrawSolidSymbol(gl, s);
}
};
private DrawSymbol draw3DSolidSymbol = new DrawSymbol() {
public void drawCharacter(GL gl, char s) {
glfDraw3DSolidSymbol(gl, s);
}
};
/* Initialization of GLF library, should be called before use of library */
public void glfInit() {
int i;
refNumber++;
if (refNumber > 1) return;
for (i = 0; i < MAX_FONTS; i++) {
fonts[i] = null;
bmf_in_use[i] = false;
m_max_height[i] = 0;
}
curfont = -1;
bmf_curfont = -1;
console_msg = GLF_NO;
ap = GLF_CENTER; /* Set anchor point to center of each symbol */
texturing = GLF_NO; /* By default texturing is NOT Enabled */
contouring = GLF_NO; /* By default contouring is NOT Enabled */
contouring_color = new float[]{0, 0, 0, 1};
conData = null;
glfSetConsoleParam(40, 20);
glfConsoleClear();
glfEnable(GLF_CONSOLE_CURSOR);
glfSetCursorBlinkRate(10);
glfStringCentering(false);
// glfBitmapStringCentering(false);
glfStringDirection(GLF_LEFT);
}
/* Closing library usage */
public void glfClose() {
int i;
refNumber--;
if (refNumber > 0) return;
conData = null;
for (i = 0; i < MAX_FONTS; i++) glfUnloadFontD(i);
// for (i = 0; i < MAX_FONTS; i++) glfUnloadBFontD(gl, i);
}
/*
---------------------------------------------------------------------------------
------------------------ Work with vector fonts ---------------------------------
---------------------------------------------------------------------------------
*/
/**
* This function read font file and store information in memory
* @return GLF_OK if succesfull; GLF_ERROR otherwise
*/
private int readFont(String font_name, GLFFont glff) {
LittleEndianDataInputStream inputStream = null;
try {
// Try to load resource from jar
InputStream stream = ClassLoader.getSystemResourceAsStream(font_name);
// If not found in jar, then load from disk
if (stream == null) {
inputStream = new LittleEndianDataInputStream(new BufferedInputStream(new FileInputStream(font_name)));
} else {
inputStream = new LittleEndianDataInputStream(new BufferedInputStream(stream));
}
byte[] buffer = new byte[3];
inputStream.readFully(buffer);
byte[] header = new byte[]{'G', 'L', 'F'};
if (!Arrays.equals(buffer, header)) {
return GLF_ERROR;
}
StringBuffer name = new StringBuffer();
for (int i = 0; i < 96; i++) {
char readChar = (char) inputStream.readUnsignedByte();
if (readChar != 0)
name.append(readChar);
}
glff.font_name = name.toString();
glff.sym_total = inputStream.readUnsignedByte(); /* Read total symbols in font */
for (int i = 0; i < glff.symbols.length; i++)
glff.symbols[i] = null;
for (int i = 0; i < 28; i++)
inputStream.read(); /* Skip unused data */
/* Now start to read font data */
for (int i = 0; i < glff.sym_total; i++) {
int code = inputStream.readUnsignedByte();
int verts = inputStream.readUnsignedByte();
int fcets = inputStream.readUnsignedByte();
int lns = inputStream.readUnsignedByte();
if (glff.symbols[code] != null) {
return GLF_ERROR;
}
glff.symbols[code] = new Symbol();
glff.symbols[code].vdata = new float[8 * verts];
glff.symbols[code].fdata = new int[3 * fcets];
glff.symbols[code].ldata = new int[lns];
glff.symbols[code].vertexs = verts;
glff.symbols[code].facets = fcets;
glff.symbols[code].lines = lns;
/* Read vertexs data */
glff.symbols[code].leftx = 10;
glff.symbols[code].rightx = -10;
glff.symbols[code].topy = 10;
glff.symbols[code].bottomy = -10;
for (int j = 0; j < verts; j++) {
float tempfx = inputStream.readFloat();
float tempfy = inputStream.readFloat();
glff.symbols[code].vdata[j * 2] = tempfx;
glff.symbols[code].vdata[j * 2 + 1] = tempfy;
if (tempfx < glff.symbols[code].leftx) glff.symbols[code].leftx = tempfx;
if (tempfx > glff.symbols[code].rightx) glff.symbols[code].rightx = tempfx;
if (tempfy < glff.symbols[code].topy) glff.symbols[code].topy = tempfy;
if (tempfy > glff.symbols[code].bottomy) glff.symbols[code].bottomy = tempfy;
}
for (int j = 0; j < fcets; j++) {
glff.symbols[code].fdata[j * 3] = inputStream.readUnsignedByte();
glff.symbols[code].fdata[j * 3 + 1] = inputStream.readUnsignedByte();
glff.symbols[code].fdata[j * 3 + 2] = inputStream.readUnsignedByte();
}
for (int j = 0; j < lns; j++) {
glff.symbols[code].ldata[j] = inputStream.readUnsignedByte();
}
}
return GLF_OK;
} catch (IOException e) {
return GLF_ERROR;
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
}
}
}
/*
| Function loads font to memory from file
| Return value: GLF_ERROR - if error
| >=0 - returned font descriptor (load success)
*/
public int glfLoadFont(String fontf) {
/* First we find free font descriptor */
boolean flag = false; /* Descriptor not found yet */
int i = 0;
for (; i < MAX_FONTS; i++)
if (fonts[i] == null) {
/* Initialize this font */
fonts[i] = new GLFFont();
flag = true;
break;
}
if (!flag) return GLF_ERROR; /* Free font not found */
if (readFont(fontf, fonts[i]) == GLF_OK) {
curfont = i; /* Set curfont to just loaded font */
return i;
}
if (fonts[i] != null) {
fonts[i] = null;
}
return GLF_ERROR;
}
/*
| Unload current font from memory
| Return value: GLF_OK - if all OK
| GLF_ERROR - if error
*/
public int glfUnloadFont() {
int i;
if ((curfont < 0) || (fonts[curfont] == null)) return GLF_ERROR;
for (i = 0; i < 256; i++) {
if (fonts[curfont].symbols[i] != null) {
fonts[curfont].symbols[i].vdata = null;
fonts[curfont].symbols[i].fdata = null;
fonts[curfont].symbols[i].ldata = null;
fonts[curfont].symbols[i] = null;
}
}
fonts[curfont] = null;
curfont = -1;
return GLF_OK;
}
/* Unload font by font descriptor */
public int glfUnloadFontD(int font_descriptor) {
int temp;
if ((font_descriptor < 0) || (fonts[font_descriptor] == null)) return GLF_ERROR;
temp = curfont;
curfont = font_descriptor;
glfUnloadFont();
if (temp != font_descriptor)
curfont = temp;
else
curfont = -1;
return GLF_OK;
}
public void glfDrawWiredSymbol(GL gl, char s) {
int i, cur_line;
int tvp; /* temporary vertex pointer */
float x, y;
if ((curfont < 0) || (fonts[curfont] == null)) return;
if (fonts[curfont].symbols[s] == null) return;
gl.glBegin(GL.GL_LINE_LOOP);
tvp = 0;
cur_line = 0;
for (i = 0; i < fonts[curfont].symbols[s].vertexs; i++) {
x = fonts[curfont].symbols[s].vdata[tvp++];
y = fonts[curfont].symbols[s].vdata[tvp++];
gl.glVertex2f(x, y);
if (fonts[curfont].symbols[s].ldata[cur_line] == i) {
gl.glEnd();
cur_line++;
if (cur_line < fonts[curfont].symbols[s].lines)
gl.glBegin(GL.GL_LINE_LOOP);
else
break; /* No more lines */
}
}
}
/* Draw wired symbol by font_descriptor */
public void glfDrawWiredSymbolF(GL gl, int font_descriptor, char s) {
int temp;
temp = curfont;
curfont = font_descriptor;
glfDrawWiredSymbol(gl, s);
curfont = temp;
}
private void DrawString(GL gl, String s, DrawSymbol funct) {
int i;
float sda, sdb;
float distance = 0f;
if (s == null) return;
if (s.length() == 0) return;
if (curfont == -1) return;
/* Calculate correction (if string centering enabled) */
if (m_string_center) {
distance = 0;
for (i = 0; i < s.length(); i++) {
if ((fonts[curfont].symbols[s.charAt(i)] == null) || (s.charAt(i) == ' ')) {
if (m_direction == GLF_LEFT || m_direction == GLF_UP)
distance += SpaceSize;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -