This commit is contained in:
parent
257d7e9db5
commit
98c96ed24d
12 changed files with 782 additions and 22 deletions
|
|
@ -92,6 +92,8 @@ public class LWJGLGameWindow {
|
|||
GL11.glShadeModel(GL11.GL_SMOOTH);
|
||||
// disable the OpenGL depth test since we're rendering 2D graphics
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
//GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
|
||||
//GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
|
||||
// disable lights (we do not nead them)
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
// Enable Smooth Shading
|
||||
|
|
@ -101,6 +103,7 @@ public class LWJGLGameWindow {
|
|||
// Depth Buffer Setup
|
||||
GL11.glClearDepth(1.0f);
|
||||
|
||||
|
||||
//Select The Projection Matrix
|
||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||
//Reset The Projection Matrix
|
||||
|
|
@ -114,9 +117,9 @@ public class LWJGLGameWindow {
|
|||
|
||||
//Enable Blending
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
//GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
// Enable vsync if we can (due to how OpenGL works, it cannot be guarenteed to always work)
|
||||
Display.setVSyncEnabled(true);
|
||||
|
||||
|
|
|
|||
92
src/ei/engine/effects/BitmapText.java
Normal file
92
src/ei/engine/effects/BitmapText.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package ei.engine.effects;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import ei.engine.scene.Entity;
|
||||
import ei.engine.texture.Texture;
|
||||
import ei.engine.texture.TextureLoader;
|
||||
|
||||
/**
|
||||
* Displays text on the screen by a bitmap
|
||||
* @author Ziver
|
||||
*
|
||||
*/
|
||||
|
||||
public class BitmapText extends Entity{
|
||||
private static final int CHAR_SIZE = 10;
|
||||
private Texture texture;
|
||||
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Create a Text object
|
||||
*
|
||||
* @param name The name of this entity
|
||||
*/
|
||||
public BitmapText(String name) {
|
||||
super(name);
|
||||
texture = TextureLoader.getTextureLoaderInstance().getTexture("data/font.png");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text to be displayed
|
||||
*
|
||||
* @param msg The text
|
||||
*/
|
||||
public void setText(String msg){
|
||||
text = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the text
|
||||
*/
|
||||
public void render(){
|
||||
if(text != null && !text.isEmpty()){
|
||||
// store the current model matrix
|
||||
GL11.glPushMatrix();
|
||||
|
||||
//Sets the location
|
||||
super.setTranslationGL();
|
||||
// No rotation enabled
|
||||
//super.setRotationGL(texture.getImageWidth()/2,texture.getImageHeight()/2);
|
||||
//Sets the scale of the sprite
|
||||
super.setScaleGL();
|
||||
|
||||
texture.bindGL();
|
||||
|
||||
for(int i=0; i<text.length() ;i++) {
|
||||
int c = text.charAt(i);
|
||||
float y = c/16;
|
||||
float x = c-(16*y);
|
||||
y /= texture.getImageHeight();
|
||||
x /= texture.getImageWidth();
|
||||
float size = (float)CHAR_SIZE/texture.getImageWidth();
|
||||
|
||||
System.out.println("lol: "+x+" - "+y+" - "+size);
|
||||
|
||||
GL11.glBegin(GL11.GL_QUADS);
|
||||
GL11.glTexCoord2f(x, y);
|
||||
GL11.glVertex3f(-0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((x + size), y);
|
||||
GL11.glVertex3f(0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((x + size), y - size);
|
||||
GL11.glVertex3f(0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f(x, y - size);
|
||||
GL11.glVertex3f(-0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glEnd();
|
||||
|
||||
GL11.glTranslatef(size, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
// restore the model view matrix to prevent contamination
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle getBound() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,5 @@
|
|||
package ei.engine.effects;
|
||||
|
||||
/*
|
||||
* This Code Was Created By Jeff Molofee and GB Schmick 2000
|
||||
* A HUGE Thanks To Fredric Echols For Cleaning Up
|
||||
* And Optimizing The Base Code, Making It More Flexible!
|
||||
* If You've Found This Code Useful, Please Let Me Know.
|
||||
* Visit Our Sites At www.tiptup.com and nehe.gamedev.net
|
||||
*/
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
|
@ -26,10 +18,6 @@ import ei.engine.texture.TextureLoader;
|
|||
* Title: Particle Engine Using Triangle Strips
|
||||
* Uses version 0.9alpha of LWJGL http://www.lwjgl.org/
|
||||
*
|
||||
* Be sure that the LWJGL libraries are in your classpath
|
||||
*
|
||||
* Ported directly from the C++ version
|
||||
*
|
||||
*/
|
||||
public class Particles extends Entity{
|
||||
public boolean regenerate = true;
|
||||
|
|
|
|||
239
src/ei/engine/effects/Text.java
Normal file
239
src/ei/engine/effects/Text.java
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
package ei.engine.effects;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import ei.engine.scene.Entity;
|
||||
|
||||
public class Text extends Entity{
|
||||
//build colours for font with alpha transparency
|
||||
private static final Color OPAQUE_WHITE = new Color(0xFFFFFFFF, true);
|
||||
private static final Color TRANSPARENT_BLACK = new Color(0x00000000, true);
|
||||
|
||||
// Base Display List For The Font Set
|
||||
private int base;
|
||||
private int texture;
|
||||
|
||||
// Name of the font to use
|
||||
private String fontName = "Courier New";
|
||||
private int fontSize = 24;
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* Create a Text object
|
||||
*
|
||||
* @param name The name of this entity
|
||||
*/
|
||||
public Text(String name) {
|
||||
super(name);
|
||||
buildFont();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text to be displayed
|
||||
*
|
||||
* @param msg The text
|
||||
*/
|
||||
public void setText(String msg){
|
||||
text = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the text
|
||||
*/
|
||||
public void render(){
|
||||
// store the current model matrix
|
||||
GL11.glPushMatrix();
|
||||
|
||||
//Sets the location
|
||||
super.setTranslationGL();
|
||||
// No rotation enabled
|
||||
//super.setRotationGL(texture.getImageWidth()/2,texture.getImageHeight()/2);
|
||||
//Sets the scale of the sprite
|
||||
super.setScaleGL();
|
||||
|
||||
GL11.glColor3f(0.5f, 0.5f, 0.5f);
|
||||
if(text != null) {
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
|
||||
for(int i=0; i<text.length() ;i++) {
|
||||
GL11.glCallList(base + text.charAt(i));
|
||||
GL11.glTranslatef(0.05f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// restore the model view matrix to prevent contamination
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a image out of the font and puts it in opengl
|
||||
* @author Mark Bernard
|
||||
*/
|
||||
private void buildFont() { // Build Our Bitmap Font
|
||||
Font font; // Font object
|
||||
|
||||
/* Note that I have set the font to Courier New. This font is not guraunteed to be on all
|
||||
* systems. However it is very common so it is likely to be there. You can replace this name
|
||||
* with any named font on your system or use the Java default names that are guraunteed to be there.
|
||||
* Also note that this will work well with monospace fonts, but does not look as good with
|
||||
* proportional fonts.
|
||||
*/
|
||||
BufferedImage fontImage; // image for creating the bitmap
|
||||
int bitmapSize = 512; // set the size for the bitmap texture
|
||||
boolean sizeFound = false;
|
||||
boolean directionSet = false;
|
||||
int delta = 0;
|
||||
|
||||
/* To find out how much space a Font takes, you need to use a the FontMetrics class.
|
||||
* To get the FontMetrics, you need to get it from a Graphics context. A Graphics context is
|
||||
* only available from a displayable surface, ie any class that subclasses Component or any Image.
|
||||
* First the font is set on a Graphics object. Then get the FontMetrics and find out the width
|
||||
* and height of the widest character (W). Then take the largest of the 2 values and find the
|
||||
* maximum size font that will fit in the size allocated.
|
||||
*/
|
||||
while(!sizeFound) {
|
||||
font = new Font(fontName, Font.PLAIN, fontSize); // Font Name
|
||||
// use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
|
||||
fontImage = new BufferedImage(bitmapSize, bitmapSize, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D g = (Graphics2D)fontImage.getGraphics();
|
||||
g.setFont(font);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int width = fm.stringWidth("W");
|
||||
int height = fm.getHeight();
|
||||
int lineWidth = (width > height) ? width * 16 : height * 16;
|
||||
if(!directionSet) {
|
||||
if(lineWidth > bitmapSize) {
|
||||
delta = -2;
|
||||
}
|
||||
else {
|
||||
delta = 2;
|
||||
}
|
||||
directionSet = true;
|
||||
}
|
||||
if(delta > 0) {
|
||||
if(lineWidth < bitmapSize) {
|
||||
fontSize += delta;
|
||||
}
|
||||
else {
|
||||
sizeFound = true;
|
||||
fontSize -= delta;
|
||||
}
|
||||
}
|
||||
else if(delta < 0) {
|
||||
if(lineWidth > bitmapSize) {
|
||||
fontSize += delta;
|
||||
}
|
||||
else {
|
||||
sizeFound = true;
|
||||
fontSize -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that a font size has been determined, create the final image, set the font and draw the
|
||||
* standard/extended ASCII character set for that font.
|
||||
*/
|
||||
font = new Font(fontName, Font.BOLD, fontSize); // Font Name
|
||||
// use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
|
||||
fontImage = new BufferedImage(bitmapSize, bitmapSize, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D g = (Graphics2D)fontImage.getGraphics();
|
||||
g.setFont(font);
|
||||
g.setColor(OPAQUE_WHITE);
|
||||
g.setBackground(TRANSPARENT_BLACK);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
for(int i=0;i<256;i++) {
|
||||
int x = i % 16;
|
||||
int y = i / 16;
|
||||
char ch[] = {(char)i};
|
||||
String temp = new String(ch);
|
||||
g.drawString(temp, (x * 32) + 1, (y * 32) + fm.getAscent());
|
||||
}
|
||||
|
||||
/* The following code is taken directly for the LWJGL example code.
|
||||
* It takes a Java Image and converts it into an OpenGL texture.
|
||||
* This is a very powerful feature as you can use this to generate textures on the fly out
|
||||
* of anything.
|
||||
*/
|
||||
// Flip Image
|
||||
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
|
||||
tx.translate(0, -fontImage.getHeight(null));
|
||||
AffineTransformOp op =
|
||||
new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
fontImage = op.filter(fontImage, null);
|
||||
|
||||
// Put Image In Memory
|
||||
ByteBuffer scratch =
|
||||
ByteBuffer.allocateDirect(
|
||||
4 * fontImage.getWidth() * fontImage.getHeight());
|
||||
|
||||
byte data[] =
|
||||
(byte[])fontImage.getRaster().getDataElements(
|
||||
0,
|
||||
0,
|
||||
fontImage.getWidth(),
|
||||
fontImage.getHeight(),
|
||||
null);
|
||||
scratch.clear();
|
||||
scratch.put(data);
|
||||
scratch.rewind();
|
||||
|
||||
// Create A IntBuffer For Image Address In Memory
|
||||
IntBuffer buf =
|
||||
ByteBuffer
|
||||
.allocateDirect(4)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asIntBuffer();
|
||||
GL11.glGenTextures(buf); // Create Texture In OpenGL
|
||||
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
|
||||
// Typical Texture Generation Using Data From The Image
|
||||
|
||||
// Linear Filtering
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
|
||||
// Linear Filtering
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
|
||||
// Generate The Texture
|
||||
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, fontImage.getWidth(), fontImage.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, scratch);
|
||||
|
||||
|
||||
texture = buf.get(0); // Return Image Address In Memory
|
||||
|
||||
base = GL11.glGenLists(256); // Storage For 256 Characters
|
||||
|
||||
/* Generate the display lists. One for each character in the standard/extended ASCII chart.
|
||||
*/
|
||||
float textureDelta = 1.0f / 16.0f;
|
||||
for(int i=0;i<256;i++) {
|
||||
float u = ((float)(i % 16)) / 16.0f;
|
||||
float v = 1.f - (((float)(i / 16)) / 16.0f);
|
||||
GL11.glNewList(base + i, GL11.GL_COMPILE);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
|
||||
GL11.glBegin(GL11.GL_QUADS);
|
||||
GL11.glTexCoord2f(u, v);
|
||||
GL11.glVertex3f(-0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((u + textureDelta), v);
|
||||
GL11.glVertex3f(0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((u + textureDelta), v - textureDelta);
|
||||
GL11.glVertex3f(0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f(u, v - textureDelta);
|
||||
GL11.glVertex3f(-0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glEnd();
|
||||
GL11.glEndList();
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle getBound() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -58,8 +58,18 @@ public class Vector3f {
|
|||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the z value
|
||||
*
|
||||
* @param z the z value
|
||||
*/
|
||||
public void setZ(float z){
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the vector
|
||||
*
|
||||
* @param i The amount to add
|
||||
*/
|
||||
public void add(float i){
|
||||
|
|
@ -70,6 +80,7 @@ public class Vector3f {
|
|||
|
||||
/**
|
||||
* Add to the vector
|
||||
*
|
||||
* @param i The amount to add
|
||||
*/
|
||||
public void add(Vector3f i){
|
||||
|
|
@ -80,6 +91,7 @@ public class Vector3f {
|
|||
|
||||
/**
|
||||
* Add to the vector
|
||||
*
|
||||
* @param i The amount to add
|
||||
*/
|
||||
public void add(Vector2f i){
|
||||
|
|
@ -89,6 +101,7 @@ public class Vector3f {
|
|||
|
||||
/**
|
||||
* Add to the vector
|
||||
*
|
||||
* @param x The value to add to the x value
|
||||
* @param y The value to add to the y value
|
||||
* @param z The value to add to the z value
|
||||
|
|
@ -99,7 +112,16 @@ public class Vector3f {
|
|||
this.z += z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this vector
|
||||
*
|
||||
* @return A copy of this vector
|
||||
*/
|
||||
public Vector3f getCopy(){
|
||||
return new Vector3f(x,y,z);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "Vector2f["+x+","+y+"]";
|
||||
return "Vector3f["+x+","+y+","+z+"]";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,14 @@ public class Node extends Sprite {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean remove(Entity e){
|
||||
if(entities.contains(e)){
|
||||
entities.remove(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw all the Entities in the node
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ei.engine.test;
|
|||
import ei.engine.LWJGLGameWindow;
|
||||
import ei.engine.effects.Particles;
|
||||
import ei.engine.math.Vector2f;
|
||||
import ei.engine.math.Vector3f;
|
||||
import ei.engine.scene.Node;
|
||||
import ei.engine.scene.Sprite;
|
||||
import ei.engine.sound.Sound;
|
||||
|
|
@ -21,11 +22,12 @@ public class GameStateTestState extends GameState{
|
|||
|
||||
sprite1 = new Sprite("tank","data/units/tank.png");
|
||||
//sprite1.setScale(new Vector2f(0.5f,0.5f));
|
||||
//sprite1.setLocation(new Vector2f(300,300));
|
||||
sprite1.setLocation(new Vector3f(0,0,0.2f));
|
||||
rootNode.add(sprite1);
|
||||
|
||||
p = new Particles("particle");
|
||||
p.setLocation(sprite1.getLocation());
|
||||
p.setLocation(sprite1.getLocation().getCopy());
|
||||
p.getLocation().setZ(0.1f);
|
||||
rootNode.add(p);
|
||||
|
||||
sound1 = new Sound("sound","data/sounds/center.wav");
|
||||
|
|
|
|||
39
src/ei/engine/test/TextTest.java
Normal file
39
src/ei/engine/test/TextTest.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package ei.engine.test;
|
||||
|
||||
import ei.engine.LWJGLGameWindow;
|
||||
import ei.engine.effects.BitmapText;
|
||||
import ei.engine.effects.Text;
|
||||
import ei.engine.math.Vector2f;
|
||||
|
||||
public class TextTest extends LWJGLGameWindow{
|
||||
private BitmapText text;
|
||||
private float pos;
|
||||
|
||||
public static void main(String[] args){
|
||||
new TextTest();
|
||||
}
|
||||
|
||||
public TextTest() {
|
||||
super("TextTest");
|
||||
}
|
||||
|
||||
protected void init(){
|
||||
text = new BitmapText("Test text");
|
||||
text.setText("LOL THIS IS A TEST!!");
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
protected void update() {
|
||||
super.update();
|
||||
pos += 0.2f;
|
||||
text.setLocation(new Vector2f(200,200));
|
||||
text.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* this method shid be overriden
|
||||
*/
|
||||
protected void render(){
|
||||
text.render();
|
||||
}
|
||||
}
|
||||
|
|
@ -46,12 +46,12 @@ import org.lwjgl.opengl.DisplayMode;
|
|||
* @version $Revision$
|
||||
* $Id$
|
||||
*/
|
||||
public abstract class BasicTest {
|
||||
public abstract class BasicSoundTest {
|
||||
|
||||
/**
|
||||
* Creates an instance of PlayTest
|
||||
*/
|
||||
public BasicTest() {
|
||||
public BasicSoundTest() {
|
||||
try {
|
||||
String[] imps = AL.getImplementations();
|
||||
if(imps.length > 0) {
|
||||
367
src/ei/engine/test/ex/FontTest.java
Normal file
367
src/ei/engine/test/ex/FontTest.java
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
package ei.engine.test.ex;
|
||||
|
||||
/*
|
||||
* This Code Was Created By Jeff Molofee 2000
|
||||
* Modified by Shawn T. to handle (%3.2f, num) parameters.
|
||||
* A HUGE Thanks To Fredric Echols For Cleaning Up
|
||||
* And Optimizing The Base Code, Making It More Flexible!
|
||||
* If You've Found This Code Useful, Please Let Me Know.
|
||||
* Visit My Site At nehe.gamedev.net
|
||||
*/
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.DisplayMode;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.glu.GLU;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
/**
|
||||
* @author Mark Bernard
|
||||
* date: 26-May-2004
|
||||
*
|
||||
* Port of NeHe's Lesson 13 to LWJGL
|
||||
* Title: Bitmap fonts
|
||||
* Uses version 0.9alpha of LWJGL http://www.lwjgl.org/
|
||||
*
|
||||
* Be sure that the LWJGL libraries are in your classpath
|
||||
*
|
||||
* Ported directly from the C++ version
|
||||
*
|
||||
* The main point of this tutorial is to get fonts on the screen. The original OpenGL did
|
||||
* not port directly as it used Windows specific extensions and I could not get some OpenGL
|
||||
* commands to work. In the end, what you see on the screen is the same, but it is written
|
||||
* somewhat differently. I have noted the differences in the code with comments.
|
||||
*
|
||||
* 2004-10-08: Updated to version 0.92alpha of LWJGL.
|
||||
* 2004-12-19: Updated to version 0.94alpha of LWJGL
|
||||
*/
|
||||
public class FontTest {
|
||||
private boolean done = false;
|
||||
private boolean fullscreen = false;
|
||||
private final String windowTitle = "NeHe's OpenGL Lesson 13 for LWJGL (Bitmap Fonts)";
|
||||
private boolean f1 = false;
|
||||
private DisplayMode displayMode;
|
||||
|
||||
private int texture;
|
||||
|
||||
//build colours for font with alpha transparency
|
||||
private static final Color OPAQUE_WHITE = new Color(0xFFFFFFFF, true);
|
||||
private static final Color TRANSPARENT_BLACK = new Color(0x00000000, true);
|
||||
private NumberFormat numberFormat = NumberFormat.getInstance();
|
||||
|
||||
private int base; // Base Display List For The Font Set
|
||||
private float cnt1; // 1st Counter Used To Move Text & For Coloring
|
||||
private float cnt2; // 2nd Counter Used To Move Text & For Coloring
|
||||
|
||||
public static void main(String args[]) {
|
||||
boolean fullscreen = false;
|
||||
if(args.length>0) {
|
||||
if(args[0].equalsIgnoreCase("fullscreen")) {
|
||||
fullscreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
FontTest l13 = new FontTest();
|
||||
l13.run(fullscreen);
|
||||
}
|
||||
public void run(boolean fullscreen) {
|
||||
this.fullscreen = fullscreen;
|
||||
try {
|
||||
init();
|
||||
while (!done) {
|
||||
mainloop();
|
||||
render();
|
||||
Display.update();
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
private void mainloop() {
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { // Exit if Escape is pressed
|
||||
done = true;
|
||||
}
|
||||
if(Display.isCloseRequested()) { // Exit if window is closed
|
||||
done = true;
|
||||
}
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_F1) && !f1) { // Is F1 Being Pressed?
|
||||
f1 = true; // Tell Program F1 Is Being Held
|
||||
switchMode(); // Toggle Fullscreen / Windowed Mode
|
||||
}
|
||||
if(!Keyboard.isKeyDown(Keyboard.KEY_F1)) { // Is F1 Being Pressed?
|
||||
f1 = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void switchMode() {
|
||||
fullscreen = !fullscreen;
|
||||
try {
|
||||
Display.setFullscreen(fullscreen);
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean render() {
|
||||
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
|
||||
GL11.glLoadIdentity(); // Reset The Current Modelview Matrix
|
||||
|
||||
// Position The Text On The Screen
|
||||
GL11.glTranslatef(-0.9f + 0.05f * ((float)Math.cos(cnt1)), 0.32f * ((float)Math.sin(cnt2)), -2.0f); // Move One Unit Into The Screen
|
||||
|
||||
// Pulsing Colors Based On Text Position
|
||||
float red = 1.0f * ((float)Math.cos(cnt1));
|
||||
float green = 1.0f * ((float)Math.sin(cnt2));
|
||||
float blue = 1.0f - 0.5f * ((float)Math.cos(cnt1 + cnt2));
|
||||
GL11.glColor3f(red, green, blue);
|
||||
|
||||
//format the floating point number to 2 decimal places
|
||||
numberFormat.setMaximumFractionDigits(2);
|
||||
numberFormat.setMinimumFractionDigits(2);
|
||||
|
||||
glPrint("Active OpenGL Text With NeHe - " + numberFormat.format(cnt1)); // Print GL Text To The Screen
|
||||
cnt1 += 0.051f; // Increase The First Counter
|
||||
cnt2 += 0.005f; // Increase The Second Counter
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Some liberties had to be taken with this method. I could not get the glCallLists() to work, so
|
||||
* it is done manually instead.
|
||||
*/
|
||||
private void glPrint(String msg) { // Custom GL "Print" Routine
|
||||
if(msg != null) {
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
|
||||
for(int i=0;i<msg.length();i++) {
|
||||
GL11.glCallList(base + msg.charAt(i));
|
||||
GL11.glTranslatef(0.05f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createWindow() throws Exception {
|
||||
Display.setFullscreen(fullscreen);
|
||||
DisplayMode d[] = Display.getAvailableDisplayModes();
|
||||
for (int i = 0; i < d.length; i++) {
|
||||
if (d[i].getWidth() == 640
|
||||
&& d[i].getHeight() == 480
|
||||
&& d[i].getBitsPerPixel() == 32) {
|
||||
displayMode = d[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
Display.setDisplayMode(displayMode);
|
||||
Display.setTitle(windowTitle);
|
||||
Display.create();
|
||||
}
|
||||
private void init() throws Exception {
|
||||
createWindow();
|
||||
|
||||
initGL();
|
||||
buildFont();
|
||||
}
|
||||
private void initGL() {
|
||||
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
|
||||
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
// Black Background
|
||||
GL11.glClearDepth(1.0); // Depth Buffer Setup
|
||||
GL11.glDepthFunc(GL11.GL_LEQUAL);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
|
||||
//GL11.glEnable(GL11.GL_CULL_FACE);
|
||||
// The Type Of Depth Testing To Do
|
||||
|
||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||
// Select The Projection Matrix
|
||||
GL11.glLoadIdentity(); // Reset The Projection Matrix
|
||||
|
||||
// Calculate The Aspect Ratio Of The Window
|
||||
GLU.gluPerspective(45.0f,
|
||||
(float) displayMode.getWidth() / (float) displayMode.getHeight(),
|
||||
0.1f,100.0f);
|
||||
GL11.glMatrixMode(GL11.GL_MODELVIEW);
|
||||
// Select The Modelview Matrix
|
||||
|
||||
// Really Nice Perspective Calculations
|
||||
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
|
||||
}
|
||||
private void cleanup() {
|
||||
Display.destroy();
|
||||
}
|
||||
|
||||
/* The original tutorial number 13 used a windows specific extension to generate a bitmap
|
||||
* for the font. I had to replace that with a custom bitmap generation that you see below.
|
||||
*
|
||||
*/
|
||||
private void buildFont() { // Build Our Bitmap Font
|
||||
Font font; // Font object
|
||||
|
||||
/* Note that I have set the font to Courier New. This font is not guraunteed to be on all
|
||||
* systems. However it is very common so it is likely to be there. You can replace this name
|
||||
* with any named font on your system or use the Java default names that are guraunteed to be there.
|
||||
* Also note that this will work well with monospace fonts, but does not look as good with
|
||||
* proportional fonts.
|
||||
*/
|
||||
String fontName = "Courier New"; // Name of the font to use
|
||||
BufferedImage fontImage; // image for creating the bitmap
|
||||
int bitmapSize = 512; // set the size for the bitmap texture
|
||||
boolean sizeFound = false;
|
||||
boolean directionSet = false;
|
||||
int delta = 0;
|
||||
int fontSize = 24;
|
||||
|
||||
/* To find out how much space a Font takes, you need to use a the FontMetrics class.
|
||||
* To get the FontMetrics, you need to get it from a Graphics context. A Graphics context is
|
||||
* only available from a displayable surface, ie any class that subclasses Component or any Image.
|
||||
* First the font is set on a Graphics object. Then get the FontMetrics and find out the width
|
||||
* and height of the widest character (W). Then take the largest of the 2 values and find the
|
||||
* maximum size font that will fit in the size allocated.
|
||||
*/
|
||||
while(!sizeFound) {
|
||||
font = new Font(fontName, Font.PLAIN, fontSize); // Font Name
|
||||
// use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
|
||||
fontImage = new BufferedImage(bitmapSize, bitmapSize, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D g = (Graphics2D)fontImage.getGraphics();
|
||||
g.setFont(font);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int width = fm.stringWidth("W");
|
||||
int height = fm.getHeight();
|
||||
int lineWidth = (width > height) ? width * 16 : height * 16;
|
||||
if(!directionSet) {
|
||||
if(lineWidth > bitmapSize) {
|
||||
delta = -2;
|
||||
}
|
||||
else {
|
||||
delta = 2;
|
||||
}
|
||||
directionSet = true;
|
||||
}
|
||||
if(delta > 0) {
|
||||
if(lineWidth < bitmapSize) {
|
||||
fontSize += delta;
|
||||
}
|
||||
else {
|
||||
sizeFound = true;
|
||||
fontSize -= delta;
|
||||
}
|
||||
}
|
||||
else if(delta < 0) {
|
||||
if(lineWidth > bitmapSize) {
|
||||
fontSize += delta;
|
||||
}
|
||||
else {
|
||||
sizeFound = true;
|
||||
fontSize -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that a font size has been determined, create the final image, set the font and draw the
|
||||
* standard/extended ASCII character set for that font.
|
||||
*/
|
||||
font = new Font(fontName, Font.BOLD, fontSize); // Font Name
|
||||
// use BufferedImage.TYPE_4BYTE_ABGR to allow alpha blending
|
||||
fontImage = new BufferedImage(bitmapSize, bitmapSize, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics2D g = (Graphics2D)fontImage.getGraphics();
|
||||
g.setFont(font);
|
||||
g.setColor(OPAQUE_WHITE);
|
||||
g.setBackground(TRANSPARENT_BLACK);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
for(int i=0;i<256;i++) {
|
||||
int x = i % 16;
|
||||
int y = i / 16;
|
||||
char ch[] = {(char)i};
|
||||
String temp = new String(ch);
|
||||
g.drawString(temp, (x * 32) + 1, (y * 32) + fm.getAscent());
|
||||
}
|
||||
|
||||
/* The following code is taken directly for the LWJGL example code.
|
||||
* It takes a Java Image and converts it into an OpenGL texture.
|
||||
* This is a very powerful feature as you can use this to generate textures on the fly out
|
||||
* of anything.
|
||||
*/
|
||||
// Flip Image
|
||||
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
|
||||
tx.translate(0, -fontImage.getHeight(null));
|
||||
AffineTransformOp op =
|
||||
new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
fontImage = op.filter(fontImage, null);
|
||||
|
||||
// Put Image In Memory
|
||||
ByteBuffer scratch =
|
||||
ByteBuffer.allocateDirect(
|
||||
4 * fontImage.getWidth() * fontImage.getHeight());
|
||||
|
||||
byte data[] =
|
||||
(byte[])fontImage.getRaster().getDataElements(
|
||||
0,
|
||||
0,
|
||||
fontImage.getWidth(),
|
||||
fontImage.getHeight(),
|
||||
null);
|
||||
scratch.clear();
|
||||
scratch.put(data);
|
||||
scratch.rewind();
|
||||
|
||||
// Create A IntBuffer For Image Address In Memory
|
||||
IntBuffer buf =
|
||||
ByteBuffer
|
||||
.allocateDirect(4)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asIntBuffer();
|
||||
GL11.glGenTextures(buf); // Create Texture In OpenGL
|
||||
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
|
||||
// Typical Texture Generation Using Data From The Image
|
||||
|
||||
// Linear Filtering
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
|
||||
// Linear Filtering
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
|
||||
// Generate The Texture
|
||||
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, fontImage.getWidth(), fontImage.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, scratch);
|
||||
|
||||
|
||||
texture = buf.get(0); // Return Image Address In Memory
|
||||
|
||||
base = GL11.glGenLists(256); // Storage For 256 Characters
|
||||
|
||||
/* Generate the display lists. One for each character in the standard/extended ASCII chart.
|
||||
*/
|
||||
float textureDelta = 1.0f / 16.0f;
|
||||
for(int i=0;i<256;i++) {
|
||||
float u = ((float)(i % 16)) / 16.0f;
|
||||
float v = 1.f - (((float)(i / 16)) / 16.0f);
|
||||
GL11.glNewList(base + i, GL11.GL_COMPILE);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
|
||||
GL11.glBegin(GL11.GL_QUADS);
|
||||
GL11.glTexCoord2f(u, v);
|
||||
GL11.glVertex3f(-0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((u + textureDelta), v);
|
||||
GL11.glVertex3f(0.0450f, 0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f((u + textureDelta), v - textureDelta);
|
||||
GL11.glVertex3f(0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glTexCoord2f(u, v - textureDelta);
|
||||
GL11.glVertex3f(-0.0450f, -0.0450f, 0.0f);
|
||||
GL11.glEnd();
|
||||
GL11.glEndList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ import ei.engine.util.MultiPrintStream;
|
|||
* 2004-12-19: Updated to version 0.94alpha of LWJGL and to use
|
||||
* DevIL for image loading.
|
||||
*/
|
||||
public class Lesson19 {
|
||||
public class ParticleTest {
|
||||
private boolean done = false;
|
||||
private boolean fullscreen = false;
|
||||
private final String windowTitle = "NeHe's OpenGL Lesson 19 for LWJGL (Particle Engine Using Triangle Strips)";
|
||||
|
|
@ -71,7 +71,7 @@ public class Lesson19 {
|
|||
}
|
||||
}
|
||||
|
||||
Lesson19 l19 = new Lesson19();
|
||||
ParticleTest l19 = new ParticleTest();
|
||||
l19.run(fullscreen);
|
||||
}
|
||||
public void run(boolean fullscreen) {
|
||||
|
|
@ -55,7 +55,7 @@ import org.lwjgl.util.WaveData;
|
|||
* @version $Revision$
|
||||
* $Id$
|
||||
*/
|
||||
public class SoundPositionTest extends BasicTest {
|
||||
public class SoundPositionTest extends BasicSoundTest {
|
||||
|
||||
/** *Small* glut implementation :) */
|
||||
private GLUT glut;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue