Reflecting changes in GameCore and MightyUtils

master
Ondřej Hruška 11 years ago
parent d2fe36f745
commit 2377b653cf
  1. 12
      src/mightypork/gamecore/backends/lwjgl/BufferHelper.java
  2. 7
      src/mightypork/gamecore/backends/lwjgl/InitTaskRedirectSlickLog.java
  3. 5
      src/mightypork/gamecore/backends/lwjgl/LwjglBackend.java
  4. 116
      src/mightypork/gamecore/backends/lwjgl/LwjglInputModule.java
  5. 36
      src/mightypork/gamecore/backends/lwjgl/SlickLogRedirector.java
  6. 80
      src/mightypork/gamecore/backends/lwjgl/audio/SlickAudio.java
  7. 24
      src/mightypork/gamecore/backends/lwjgl/audio/SlickAudioModule.java
  8. 20
      src/mightypork/gamecore/backends/lwjgl/graphics/AwtScreenshot.java
  9. 312
      src/mightypork/gamecore/backends/lwjgl/graphics/LwjglGraphicsModule.java
  10. 82
      src/mightypork/gamecore/backends/lwjgl/graphics/SlickTexture.java
  11. 54
      src/mightypork/gamecore/backends/lwjgl/graphics/font/LwjglFont.java
  12. 232
      src/mightypork/gamecore/backends/lwjgl/graphics/font/LwjglTextureBackedFontImpl.java

@ -12,7 +12,7 @@ import org.lwjgl.BufferUtils;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
public class BufferHelper { public class BufferHelper {
/** /**
* Create java.nio.FloatBuffer of given floats, and flip it. * Create java.nio.FloatBuffer of given floats, and flip it.
* *
@ -23,8 +23,8 @@ public class BufferHelper {
{ {
return (FloatBuffer) BufferUtils.createFloatBuffer(obj.length).put(obj).flip(); return (FloatBuffer) BufferUtils.createFloatBuffer(obj.length).put(obj).flip();
} }
/** /**
* Fill java.nio.FloatBuffer with floats or float array * Fill java.nio.FloatBuffer with floats or float array
* *
@ -36,8 +36,8 @@ public class BufferHelper {
buff.put(obj); buff.put(obj);
buff.flip(); buff.flip();
} }
/** /**
* Create new java.nio.FloatBuffer of given length * Create new java.nio.FloatBuffer of given length
* *
@ -48,5 +48,5 @@ public class BufferHelper {
{ {
return BufferUtils.createFloatBuffer(count); return BufferUtils.createFloatBuffer(count);
} }
} }

@ -35,4 +35,11 @@ public class InitTaskRedirectSlickLog extends InitTask {
{ {
return new String[] { "log" }; return new String[] { "log" };
} }
@Override
public int getPriority()
{
return PRIO_FIRST;
}
} }

@ -31,7 +31,12 @@ public class LwjglBackend extends AppBackend {
graphics.init(); graphics.init();
audio.init(); audio.init();
input.init(); input.init();
}
@Override
public void addInitTasks()
{
app.addInitTask(new InitTaskRedirectSlickLog()); app.addInitTask(new InitTaskRedirectSlickLog());
} }

@ -25,19 +25,19 @@ import org.lwjgl.opengl.Display;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
public class LwjglInputModule extends InputModule implements Updateable { public class LwjglInputModule extends InputModule implements Updateable {
/** Current mouse position */ /** Current mouse position */
private static final Vect mousePos = new Vect() { private static final Vect mousePos = new Vect() {
@Override @Override
public double x() public double x()
{ {
if (!Mouse.isInsideWindow()) return Integer.MIN_VALUE; if (!Mouse.isInsideWindow()) return Integer.MIN_VALUE;
return Mouse.getX(); return Mouse.getX();
} }
@Override @Override
public double y() public double y()
{ {
@ -46,22 +46,22 @@ public class LwjglInputModule extends InputModule implements Updateable {
return Display.getHeight() - Mouse.getY(); return Display.getHeight() - Mouse.getY();
} }
}; };
@Override @Override
protected void initDevices() protected void initDevices()
{ {
try { try {
tryCreate(); tryCreate();
Keyboard.enableRepeatEvents(false); Keyboard.enableRepeatEvents(false);
} catch (final LWJGLException e) { } catch (final LWJGLException e) {
throw new RuntimeException("Failed to initialize input devices.", e); throw new RuntimeException("Failed to initialize input devices.", e);
} }
} }
private void tryCreate() throws LWJGLException private void tryCreate() throws LWJGLException
{ {
if (Display.isCreated()) { if (Display.isCreated()) {
@ -69,13 +69,13 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keyboard.create(); Keyboard.create();
} }
} }
@Override @Override
protected void initKeyCodes() protected void initKeyCodes()
{ {
Keys.NONE.setCode(Keyboard.KEY_NONE); Keys.NONE.setCode(Keyboard.KEY_NONE);
Keys.NUM_1.setCode(Keyboard.KEY_1); Keys.NUM_1.setCode(Keyboard.KEY_1);
Keys.NUM_2.setCode(Keyboard.KEY_2); Keys.NUM_2.setCode(Keyboard.KEY_2);
Keys.NUM_3.setCode(Keyboard.KEY_3); Keys.NUM_3.setCode(Keyboard.KEY_3);
@ -86,7 +86,7 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.NUM_8.setCode(Keyboard.KEY_8); Keys.NUM_8.setCode(Keyboard.KEY_8);
Keys.NUM_9.setCode(Keyboard.KEY_9); Keys.NUM_9.setCode(Keyboard.KEY_9);
Keys.NUM_0.setCode(Keyboard.KEY_0); Keys.NUM_0.setCode(Keyboard.KEY_0);
Keys.Q.setCode(Keyboard.KEY_Q); Keys.Q.setCode(Keyboard.KEY_Q);
Keys.W.setCode(Keyboard.KEY_W); Keys.W.setCode(Keyboard.KEY_W);
Keys.E.setCode(Keyboard.KEY_E); Keys.E.setCode(Keyboard.KEY_E);
@ -113,7 +113,7 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.B.setCode(Keyboard.KEY_B); Keys.B.setCode(Keyboard.KEY_B);
Keys.N.setCode(Keyboard.KEY_N); Keys.N.setCode(Keyboard.KEY_N);
Keys.M.setCode(Keyboard.KEY_M); Keys.M.setCode(Keyboard.KEY_M);
Keys.MINUS.setCode(Keyboard.KEY_MINUS); Keys.MINUS.setCode(Keyboard.KEY_MINUS);
Keys.EQUALS.setCode(Keyboard.KEY_EQUALS); Keys.EQUALS.setCode(Keyboard.KEY_EQUALS);
Keys.SLASH.setCode(Keyboard.KEY_SLASH); Keys.SLASH.setCode(Keyboard.KEY_SLASH);
@ -125,17 +125,17 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.GRAVE.setCode(Keyboard.KEY_GRAVE); Keys.GRAVE.setCode(Keyboard.KEY_GRAVE);
Keys.COMMA.setCode(Keyboard.KEY_COMMA); Keys.COMMA.setCode(Keyboard.KEY_COMMA);
Keys.PERIOD.setCode(Keyboard.KEY_PERIOD); Keys.PERIOD.setCode(Keyboard.KEY_PERIOD);
Keys.SPACE.setCode(Keyboard.KEY_SPACE); Keys.SPACE.setCode(Keyboard.KEY_SPACE);
Keys.BACKSPACE.setCode(Keyboard.KEY_BACK); Keys.BACKSPACE.setCode(Keyboard.KEY_BACK);
Keys.TAB.setCode(Keyboard.KEY_TAB); Keys.TAB.setCode(Keyboard.KEY_TAB);
Keys.ESCAPE.setCode(Keyboard.KEY_ESCAPE); Keys.ESCAPE.setCode(Keyboard.KEY_ESCAPE);
Keys.APPS.setCode(Keyboard.KEY_APPS); Keys.APPS.setCode(Keyboard.KEY_APPS);
Keys.POWER.setCode(Keyboard.KEY_POWER); Keys.POWER.setCode(Keyboard.KEY_POWER);
Keys.SLEEP.setCode(Keyboard.KEY_SLEEP); Keys.SLEEP.setCode(Keyboard.KEY_SLEEP);
//Keys.MENU.setCode(Keyboard.KEY_MENU); // not defined //Keys.MENU.setCode(Keyboard.KEY_MENU); // not defined
Keys.F1.setCode(Keyboard.KEY_F1); Keys.F1.setCode(Keyboard.KEY_F1);
Keys.F2.setCode(Keyboard.KEY_F2); Keys.F2.setCode(Keyboard.KEY_F2);
Keys.F3.setCode(Keyboard.KEY_F3); Keys.F3.setCode(Keyboard.KEY_F3);
@ -151,11 +151,11 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.F13.setCode(Keyboard.KEY_F13); Keys.F13.setCode(Keyboard.KEY_F13);
Keys.F14.setCode(Keyboard.KEY_F14); Keys.F14.setCode(Keyboard.KEY_F14);
Keys.F15.setCode(Keyboard.KEY_F15); Keys.F15.setCode(Keyboard.KEY_F15);
Keys.CAPS_LOCK.setCode(Keyboard.KEY_CAPITAL); Keys.CAPS_LOCK.setCode(Keyboard.KEY_CAPITAL);
Keys.SCROLL_LOCK.setCode(Keyboard.KEY_SCROLL); Keys.SCROLL_LOCK.setCode(Keyboard.KEY_SCROLL);
Keys.NUM_LOCK.setCode(Keyboard.KEY_NUMLOCK); Keys.NUM_LOCK.setCode(Keyboard.KEY_NUMLOCK);
Keys.NUMPAD_MINUS.setCode(Keyboard.KEY_SUBTRACT); Keys.NUMPAD_MINUS.setCode(Keyboard.KEY_SUBTRACT);
Keys.NUMPAD_PLUSS.setCode(Keyboard.KEY_ADD); Keys.NUMPAD_PLUSS.setCode(Keyboard.KEY_ADD);
Keys.NUMPAD_0.setCode(Keyboard.KEY_NUMPAD0); Keys.NUMPAD_0.setCode(Keyboard.KEY_NUMPAD0);
@ -172,7 +172,7 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.NUMPAD_ENTER.setCode(Keyboard.KEY_NUMPADENTER); Keys.NUMPAD_ENTER.setCode(Keyboard.KEY_NUMPADENTER);
Keys.NUMPAD_DIVIDE.setCode(Keyboard.KEY_DIVIDE); Keys.NUMPAD_DIVIDE.setCode(Keyboard.KEY_DIVIDE);
Keys.NUMPAD_MULTIPLY.setCode(Keyboard.KEY_MULTIPLY); Keys.NUMPAD_MULTIPLY.setCode(Keyboard.KEY_MULTIPLY);
Keys.CONTROL_LEFT.setCode(Keyboard.KEY_LCONTROL); Keys.CONTROL_LEFT.setCode(Keyboard.KEY_LCONTROL);
Keys.CONTROL_RIGHT.setCode(Keyboard.KEY_RCONTROL); Keys.CONTROL_RIGHT.setCode(Keyboard.KEY_RCONTROL);
Keys.ALT_LEFT.setCode(Keyboard.KEY_LMENU); Keys.ALT_LEFT.setCode(Keyboard.KEY_LMENU);
@ -181,43 +181,43 @@ public class LwjglInputModule extends InputModule implements Updateable {
Keys.SHIFT_RIGHT.setCode(Keyboard.KEY_RSHIFT); Keys.SHIFT_RIGHT.setCode(Keyboard.KEY_RSHIFT);
Keys.META_LEFT.setCode(Keyboard.KEY_LMETA); Keys.META_LEFT.setCode(Keyboard.KEY_LMETA);
Keys.META_RIGHT.setCode(Keyboard.KEY_RMETA); Keys.META_RIGHT.setCode(Keyboard.KEY_RMETA);
Keys.UP.setCode(Keyboard.KEY_UP); Keys.UP.setCode(Keyboard.KEY_UP);
Keys.DOWN.setCode(Keyboard.KEY_DOWN); Keys.DOWN.setCode(Keyboard.KEY_DOWN);
Keys.LEFT.setCode(Keyboard.KEY_LEFT); Keys.LEFT.setCode(Keyboard.KEY_LEFT);
Keys.RIGHT.setCode(Keyboard.KEY_RIGHT); Keys.RIGHT.setCode(Keyboard.KEY_RIGHT);
Keys.HOME.setCode(Keyboard.KEY_HOME); Keys.HOME.setCode(Keyboard.KEY_HOME);
Keys.END.setCode(Keyboard.KEY_END); Keys.END.setCode(Keyboard.KEY_END);
Keys.PAGE_UP.setCode(Keyboard.KEY_PRIOR); Keys.PAGE_UP.setCode(Keyboard.KEY_PRIOR);
Keys.PAGE_DOWN.setCode(Keyboard.KEY_NEXT); Keys.PAGE_DOWN.setCode(Keyboard.KEY_NEXT);
Keys.RETURN.setCode(Keyboard.KEY_RETURN); Keys.RETURN.setCode(Keyboard.KEY_RETURN);
Keys.PAUSE.setCode(Keyboard.KEY_PAUSE); Keys.PAUSE.setCode(Keyboard.KEY_PAUSE);
Keys.INSERT.setCode(Keyboard.KEY_INSERT); Keys.INSERT.setCode(Keyboard.KEY_INSERT);
Keys.DELETE.setCode(Keyboard.KEY_DELETE); Keys.DELETE.setCode(Keyboard.KEY_DELETE);
Keys.SYSRQ.setCode(Keyboard.KEY_SYSRQ); Keys.SYSRQ.setCode(Keyboard.KEY_SYSRQ);
} }
@Override @Override
public void destroy() public void destroy()
{ {
Mouse.destroy(); Mouse.destroy();
Keyboard.destroy(); Keyboard.destroy();
} }
private final VectVar mouseMove = Vect.makeVar(); private final VectVar mouseMove = Vect.makeVar();
private final VectVar mouseLastPos = Vect.makeVar(); private final VectVar mouseLastPos = Vect.makeVar();
@Override @Override
public synchronized void update(double delta) public synchronized void update(double delta)
{ {
// was destroyed or not initialized // was destroyed or not initialized
if (!Display.isCreated()) return; if (!Display.isCreated()) return;
if (!Mouse.isCreated() || !Keyboard.isCreated()) { if (!Mouse.isCreated() || !Keyboard.isCreated()) {
try { try {
tryCreate(); tryCreate();
@ -225,11 +225,11 @@ public class LwjglInputModule extends InputModule implements Updateable {
Log.e(e); Log.e(e);
} }
} }
if (!Mouse.isCreated() || !Keyboard.isCreated()) return;
if (!Mouse.isCreated() || !Keyboard.isCreated()) return;
Display.processMessages(); Display.processMessages();
// sum the moves // sum the moves
mouseMove.reset(); mouseMove.reset();
mouseLastPos.reset(); mouseLastPos.reset();
@ -238,81 +238,81 @@ public class LwjglInputModule extends InputModule implements Updateable {
onMouseEvent(mouseMove, mouseLastPos); onMouseEvent(mouseMove, mouseLastPos);
wasMouse = true; wasMouse = true;
} }
if (wasMouse && !mouseMove.isZero()) { if (wasMouse && !mouseMove.isZero()) {
App.bus().send(new MouseMotionEvent(mouseLastPos, mouseMove)); App.bus().send(new MouseMotionEvent(mouseLastPos, mouseMove));
} }
while (Keyboard.next()) { while (Keyboard.next()) {
onKeyEvent(); onKeyEvent();
} }
if (Display.isCloseRequested()) { if (Display.isCloseRequested()) {
App.shutdown(); App.shutdown();
} }
} }
private void onMouseEvent(VectVar moveSum, VectVar lastPos) private void onMouseEvent(VectVar moveSum, VectVar lastPos)
{ {
final int button = Mouse.getEventButton(); final int button = Mouse.getEventButton();
final boolean down = Mouse.getEventButtonState(); final boolean down = Mouse.getEventButtonState();
final VectVar pos = Vect.makeVar(Mouse.getEventX(), Mouse.getEventY()); final VectVar pos = Vect.makeVar(Mouse.getEventX(), Mouse.getEventY());
final VectVar move = Vect.makeVar(Mouse.getEventDX(), Mouse.getEventDY()); final VectVar move = Vect.makeVar(Mouse.getEventDX(), Mouse.getEventDY());
final int wheeld = Mouse.getEventDWheel(); final int wheeld = Mouse.getEventDWheel();
// flip Y axis // flip Y axis
pos.setY(Display.getHeight() - pos.y()); pos.setY(Display.getHeight() - pos.y());
if (button != -1 || wheeld != 0) { if (button != -1 || wheeld != 0) {
App.bus().send(new MouseButtonEvent(pos.freeze(), button, down, wheeld)); App.bus().send(new MouseButtonEvent(pos.freeze(), button, down, wheeld));
} }
moveSum.setTo(moveSum.add(move)); moveSum.setTo(moveSum.add(move));
lastPos.setTo(pos); lastPos.setTo(pos);
} }
private void onKeyEvent() private void onKeyEvent()
{ {
final int key = Keyboard.getEventKey(); final int key = Keyboard.getEventKey();
final boolean down = Keyboard.getEventKeyState(); final boolean down = Keyboard.getEventKeyState();
final char c = Keyboard.getEventCharacter(); final char c = Keyboard.getEventCharacter();
App.bus().send(new KeyEvent(key, c, down)); App.bus().send(new KeyEvent(key, c, down));
} }
@Override @Override
public Vect getMousePos() public Vect getMousePos()
{ {
return mousePos; return mousePos;
} }
@Override @Override
public boolean isMouseInside() public boolean isMouseInside()
{ {
return Mouse.isInsideWindow(); return Mouse.isInsideWindow();
} }
@Override @Override
public void grabMouse(boolean grab) public void grabMouse(boolean grab)
{ {
Mouse.setGrabbed(grab); Mouse.setGrabbed(grab);
} }
@Override @Override
public boolean isKeyDown(Key key) public boolean isKeyDown(Key key)
{ {
return key.isDefined() && Keyboard.isKeyDown(key.getCode()); return key.isDefined() && Keyboard.isKeyDown(key.getCode());
} }
@Override @Override
public boolean isMouseButtonDown(int button) public boolean isMouseButtonDown(int button)
{ {

@ -12,10 +12,10 @@ import mightypork.utils.logging.writers.LogWriter;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
class SlickLogRedirector implements org.newdawn.slick.util.LogSystem { class SlickLogRedirector implements org.newdawn.slick.util.LogSystem {
LogWriter writer; LogWriter writer;
/** /**
* @param log log to redirect into * @param log log to redirect into
*/ */
@ -23,54 +23,54 @@ class SlickLogRedirector implements org.newdawn.slick.util.LogSystem {
{ {
this.writer = log; this.writer = log;
} }
@Override @Override
public void error(String msg, Throwable e) public void error(String msg, Throwable e)
{ {
writer.log(Level.SEVERE, msg, e); writer.log(Level.SEVERE, msg, e);
} }
@Override @Override
public void error(Throwable e) public void error(Throwable e)
{ {
writer.log(Level.SEVERE, null, e); writer.log(Level.SEVERE, null, e);
} }
@Override @Override
public void error(String msg) public void error(String msg)
{ {
writer.log(Level.SEVERE, msg); writer.log(Level.SEVERE, msg);
} }
@Override @Override
public void warn(String msg) public void warn(String msg)
{ {
writer.log(Level.WARNING, msg); writer.log(Level.WARNING, msg);
} }
@Override @Override
public void warn(String msg, Throwable e) public void warn(String msg, Throwable e)
{ {
writer.log(Level.WARNING, msg, e); writer.log(Level.WARNING, msg, e);
} }
@Override @Override
public void info(String msg) public void info(String msg)
{ {
writer.log(Level.INFO, msg); writer.log(Level.INFO, msg);
} }
@Override @Override
public void debug(String msg) public void debug(String msg)
{ {
writer.log(Level.FINEST, msg); writer.log(Level.FINEST, msg);
} }
} }

@ -18,18 +18,18 @@ import org.newdawn.slick.openal.SoundStore;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
public class SlickAudio extends DeferredAudio { public class SlickAudio extends DeferredAudio {
private double pauseLoopPosition = 0; private double pauseLoopPosition = 0;
private boolean looping = false; private boolean looping = false;
private boolean paused = false; private boolean paused = false;
private double lastPlayPitch = 1; private double lastPlayPitch = 1;
private double lastPlayGain = 1; private double lastPlayGain = 1;
/** Audio resource */ /** Audio resource */
private Audio backingAudio = null; private Audio backingAudio = null;
private int sourceID; private int sourceID;
/** /**
* Slick-util based sound resource * Slick-util based sound resource
* *
@ -39,124 +39,124 @@ public class SlickAudio extends DeferredAudio {
{ {
super(resourceName); super(resourceName);
} }
@Override @Override
protected void loadResource(String resource) throws IOException protected void loadResource(String resource) throws IOException
{ {
final String ext = FileUtil.getExtension(resource); final String ext = FileUtil.getExtension(resource);
try(final InputStream stream = FileUtil.getResource(resource)) { try(final InputStream stream = FileUtil.getResource(resource)) {
if (stream == null) throw new IOException("Not found: " + resource);
if (stream == null) throw new IOException("Not found: " + resource);
if (ext.equalsIgnoreCase("ogg")) { if (ext.equalsIgnoreCase("ogg")) {
backingAudio = SoundStore.get().getOgg(resource, stream); backingAudio = SoundStore.get().getOgg(resource, stream);
} else if (ext.equalsIgnoreCase("wav")) { } else if (ext.equalsIgnoreCase("wav")) {
backingAudio = SoundStore.get().getWAV(resource, stream); backingAudio = SoundStore.get().getWAV(resource, stream);
} else if (ext.equalsIgnoreCase("aif")) { } else if (ext.equalsIgnoreCase("aif")) {
backingAudio = SoundStore.get().getAIF(resource, stream); backingAudio = SoundStore.get().getAIF(resource, stream);
} else if (ext.equalsIgnoreCase("mod")) { } else if (ext.equalsIgnoreCase("mod")) {
backingAudio = SoundStore.get().getMOD(resource, stream); backingAudio = SoundStore.get().getMOD(resource, stream);
} else { } else {
throw new RuntimeException("Invalid audio file extension."); throw new RuntimeException("Invalid audio file extension.");
} }
} }
} }
@Override @Override
public void pauseLoop() public void pauseLoop()
{ {
if (!ensureLoaded()) return; if (!ensureLoaded()) return;
if (isPlaying() && looping) { if (isPlaying() && looping) {
pauseLoopPosition = backingAudio.getPosition(); pauseLoopPosition = backingAudio.getPosition();
stop(); stop();
paused = true; paused = true;
} }
} }
@Override @Override
public void resumeLoop() public void resumeLoop()
{ {
if (!ensureLoaded()) return; if (!ensureLoaded()) return;
if (looping && paused) { if (looping && paused) {
sourceID = backingAudio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true); sourceID = backingAudio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true);
backingAudio.setPosition((float) pauseLoopPosition); backingAudio.setPosition((float) pauseLoopPosition);
paused = false; paused = false;
} }
} }
@Override @Override
public void adjustGain(double gain) public void adjustGain(double gain)
{ {
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain); AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
} }
@Override @Override
public void stop() public void stop()
{ {
if (!isLoaded()) return; if (!isLoaded()) return;
backingAudio.stop(); backingAudio.stop();
paused = false; paused = false;
} }
@Override @Override
public boolean isPlaying() public boolean isPlaying()
{ {
if (!isLoaded()) return false; if (!isLoaded()) return false;
return backingAudio.isPlaying(); return backingAudio.isPlaying();
} }
@Override @Override
public boolean isPaused() public boolean isPaused()
{ {
if (!isLoaded()) return false; if (!isLoaded()) return false;
return backingAudio.isPaused(); return backingAudio.isPaused();
} }
@Override @Override
public boolean isActive() public boolean isActive()
{ {
if (!isLoaded()) return false; if (!isLoaded()) return false;
return sourceID != -1; return sourceID != -1;
} }
@Override @Override
public void play(double pitch, double gain, boolean loop, double x, double y, double z) public void play(double pitch, double gain, boolean loop, double x, double y, double z)
{ {
if (!ensureLoaded()) return; if (!ensureLoaded()) return;
this.lastPlayPitch = pitch; this.lastPlayPitch = pitch;
this.lastPlayGain = gain; this.lastPlayGain = gain;
looping = loop; looping = loop;
sourceID = backingAudio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z); sourceID = backingAudio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
} }
@Override @Override
public void destroy() public void destroy()
{ {
if (!isLoaded() || backingAudio == null) return; if (!isLoaded() || backingAudio == null) return;
backingAudio.release(); backingAudio.release();
backingAudio = null; backingAudio = null;
} }

@ -20,10 +20,10 @@ import org.newdawn.slick.openal.SoundStore;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
public class SlickAudioModule extends AudioModule { public class SlickAudioModule extends AudioModule {
private final VectVar listenerPos = Vect.makeVar(); private final VectVar listenerPos = Vect.makeVar();
@Override @Override
public void init() public void init()
{ {
@ -31,8 +31,8 @@ public class SlickAudioModule extends AudioModule {
SoundStore.get().init(); SoundStore.get().init();
setListenerPos(Vect.ZERO); setListenerPos(Vect.ZERO);
} }
@Override @Override
public void setListenerPos(Vect pos) public void setListenerPos(Vect pos)
{ {
@ -49,27 +49,27 @@ public class SlickAudioModule extends AudioModule {
BufferHelper.fill(buf6, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); BufferHelper.fill(buf6, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
AL10.alListener(AL10.AL_ORIENTATION, buf6); AL10.alListener(AL10.AL_ORIENTATION, buf6);
} }
@Override @Override
public Vect getListenerPos() public Vect getListenerPos()
{ {
return listenerPos; return listenerPos;
} }
@Override @Override
protected void deinitSoundSystem() protected void deinitSoundSystem()
{ {
SoundStore.get().clear(); SoundStore.get().clear();
AL.destroy(); AL.destroy();
} }
@Override @Override
protected DeferredAudio doCreateResource(String res) protected DeferredAudio doCreateResource(String res)
{ {
return new SlickAudio(res); return new SlickAudio(res);
} }
} }

@ -19,14 +19,14 @@ import mightypork.gamecore.graphics.Screenshot;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
public class AwtScreenshot implements Screenshot { public class AwtScreenshot implements Screenshot {
private final int width; private final int width;
private final int height; private final int height;
private final int bpp; private final int bpp;
private final ByteBuffer bytes; private final ByteBuffer bytes;
private BufferedImage image; private BufferedImage image;
/** /**
* @param width image width * @param width image width
* @param height image height * @param height image height
@ -40,8 +40,8 @@ public class AwtScreenshot implements Screenshot {
this.bpp = bpp; this.bpp = bpp;
this.bytes = buffer; this.bytes = buffer;
} }
/** /**
* Extract to an image.<br> * Extract to an image.<br>
* Subsequent calls will use a cached value. * Subsequent calls will use a cached value.
@ -51,9 +51,9 @@ public class AwtScreenshot implements Screenshot {
public BufferedImage getImage() public BufferedImage getImage()
{ {
if (image != null) return image; if (image != null) return image;
image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_RGB); image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_RGB);
// convert to a buffered image // convert to a buffered image
for (int x = 0; x < this.width; x++) { for (int x = 0; x < this.width; x++) {
for (int y = 0; y < this.height; y++) { for (int y = 0; y < this.height; y++) {
@ -64,11 +64,11 @@ public class AwtScreenshot implements Screenshot {
image.setRGB(x, this.height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b); image.setRGB(x, this.height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
} }
} }
return image; return image;
} }
/** /**
* Save to a file.<br> * Save to a file.<br>
* Cached value is used if any. * Cached value is used if any.

@ -36,7 +36,7 @@ import org.lwjgl.opengl.GL11;
* @author MightyPork * @author MightyPork
*/ */
public class LwjglGraphicsModule extends GraphicsModule { public class LwjglGraphicsModule extends GraphicsModule {
/** Currently binded color */ /** Currently binded color */
private Color activeColor = null; private Color activeColor = null;
/** Currently binded color's alpha multiplier */ /** Currently binded color's alpha multiplier */
@ -45,187 +45,187 @@ public class LwjglGraphicsModule extends GraphicsModule {
private final Stack<Color> colorPushStack = new Stack<>(); private final Stack<Color> colorPushStack = new Stack<>();
/** Currently binded texture */ /** Currently binded texture */
private SlickTexture activeTexture; private SlickTexture activeTexture;
/** Display mode used currently for the window */ /** Display mode used currently for the window */
private DisplayMode windowDisplayMode; private DisplayMode windowDisplayMode;
/** FPS the user wants */ /** FPS the user wants */
private int targetFps; private int targetFps;
/** FPS meter used for measuring actual FPS */ /** FPS meter used for measuring actual FPS */
private final FpsMeter fpsMeter = new FpsMeter(); private final FpsMeter fpsMeter = new FpsMeter();
/** Flag that at the end of frame, fullscreen should be toggled. */ /** Flag that at the end of frame, fullscreen should be toggled. */
private boolean fullscreenToggleRequested; private boolean fullscreenToggleRequested;
/** Flag that at the end of frame, fullscreen should be set. */ /** Flag that at the end of frame, fullscreen should be set. */
private boolean fullscreenSetRequested; private boolean fullscreenSetRequested;
/** State to which fullscreen should be set. */ /** State to which fullscreen should be set. */
private boolean fullscreenSetState; private boolean fullscreenSetState;
/** Current screen size */ /** Current screen size */
private static final Vect screenSize = new Vect() { private static final Vect screenSize = new Vect() {
@Override @Override
public double y() public double y()
{ {
return Display.getHeight(); return Display.getHeight();
} }
@Override @Override
public double x() public double x()
{ {
return Display.getWidth(); return Display.getWidth();
} }
}; };
/** Current screen rectangle */ /** Current screen rectangle */
private static final Rect rect = Rect.make(screenSize); private static final Rect rect = Rect.make(screenSize);
@Override @Override
public void init() public void init()
{ {
} }
@Override @Override
public void createDisplay() public void createDisplay()
{ {
try { try {
Display.create(); Display.create();
} catch (final Exception e) { } catch (final Exception e) {
throw new RuntimeException("Could not initialize display.", e); throw new RuntimeException("Could not initialize display.", e);
} }
} }
@Override @Override
public void setColor(Color color) public void setColor(Color color)
{ {
setColor(color, 1); setColor(color, 1);
} }
@Override @Override
public void setColor(Color color, double alpha) public void setColor(Color color, double alpha)
{ {
if (color == null) color = RGB.WHITE; if (color == null) color = RGB.WHITE;
// color components can change over time - must use equals() // color components can change over time - must use equals()
if (activeColorAlpha == alpha && color.equals(activeColor)) return; if (activeColorAlpha == alpha && color.equals(activeColor)) return;
activeColor = color; activeColor = color;
activeColorAlpha = alpha; activeColorAlpha = alpha;
GL11.glColor4d(color.r(), color.g(), color.b(), alpha * color.a()); GL11.glColor4d(color.r(), color.g(), color.b(), alpha * color.a());
} }
@Override @Override
public void translate(double x, double y) public void translate(double x, double y)
{ {
glTranslated(x, y, 0); glTranslated(x, y, 0);
} }
@Override @Override
public void translate(double x, double y, double z) public void translate(double x, double y, double z)
{ {
glTranslated(x, y, z); glTranslated(x, y, z);
} }
@Override @Override
public void translate(Vect offset) public void translate(Vect offset)
{ {
glTranslated(offset.x(), offset.y(), offset.z()); glTranslated(offset.x(), offset.y(), offset.z());
} }
@Override @Override
public void translateXY(Vect offset) public void translateXY(Vect offset)
{ {
glTranslated(offset.x(), offset.y(), 0); glTranslated(offset.x(), offset.y(), 0);
} }
@Override @Override
public void scale(double x, double y) public void scale(double x, double y)
{ {
glScaled(x, y, 0); glScaled(x, y, 0);
} }
@Override @Override
public void scale(double x, double y, double z) public void scale(double x, double y, double z)
{ {
glScaled(x, y, z); glScaled(x, y, z);
} }
@Override @Override
public void scale(Vect scale) public void scale(Vect scale)
{ {
glScaled(scale.x(), scale.y(), scale.z()); glScaled(scale.x(), scale.y(), scale.z());
} }
@Override @Override
public void scaleXY(double scale) public void scaleXY(double scale)
{ {
glScaled(scale, scale, 1); glScaled(scale, scale, 1);
} }
@Override @Override
public void scaleX(double scale) public void scaleX(double scale)
{ {
glScaled(scale, 1, 1); glScaled(scale, 1, 1);
} }
@Override @Override
public void scaleY(double scale) public void scaleY(double scale)
{ {
glScaled(1, scale, 1); glScaled(1, scale, 1);
} }
@Override @Override
public void scaleZ(double scale) public void scaleZ(double scale)
{ {
glScaled(1, 1, scale); glScaled(1, 1, scale);
} }
@Override @Override
public void rotateX(double angle) public void rotateX(double angle)
{ {
rotate(angle, AXIS_X); rotate(angle, AXIS_X);
} }
@Override @Override
public void rotateY(double angle) public void rotateY(double angle)
{ {
rotate(angle, AXIS_Y); rotate(angle, AXIS_Y);
} }
@Override @Override
public void rotateZ(double angle) public void rotateZ(double angle)
{ {
rotate(angle, AXIS_Z); rotate(angle, AXIS_Z);
} }
@Override @Override
public void rotate(double angle, Vect axis) public void rotate(double angle, Vect axis)
{ {
final Vect vec = axis.norm(1); final Vect vec = axis.norm(1);
glRotated(angle, vec.x(), vec.y(), vec.z()); glRotated(angle, vec.x(), vec.y(), vec.z());
} }
@Override @Override
public void pushState() public void pushState()
{ {
@ -233,8 +233,8 @@ public class LwjglGraphicsModule extends GraphicsModule {
GL11.glPushClientAttrib(GL11.GL_ALL_CLIENT_ATTRIB_BITS); GL11.glPushClientAttrib(GL11.GL_ALL_CLIENT_ATTRIB_BITS);
GL11.glPushMatrix(); GL11.glPushMatrix();
} }
@Override @Override
public void popState() public void popState()
{ {
@ -242,47 +242,47 @@ public class LwjglGraphicsModule extends GraphicsModule {
GL11.glPopClientAttrib(); GL11.glPopClientAttrib();
GL11.glPopAttrib(); GL11.glPopAttrib();
} }
@Override @Override
public void pushGeometry() public void pushGeometry()
{ {
GL11.glPushMatrix(); GL11.glPushMatrix();
} }
@Override @Override
public void popGeometry() public void popGeometry()
{ {
GL11.glPopMatrix(); GL11.glPopMatrix();
} }
@Override @Override
public void pushColor() public void pushColor()
{ {
colorPushStack.push(activeColor); colorPushStack.push(activeColor);
} }
@Override @Override
public void popColor() public void popColor()
{ {
setColor(colorPushStack.pop()); setColor(colorPushStack.pop());
} }
@Override @Override
public void quad(Rect rect) public void quad(Rect rect)
{ {
final RectDigest q = rect.digest(); final RectDigest q = rect.digest();
// disable texture // disable texture
if (activeTexture != null) { if (activeTexture != null) {
activeTexture = null; activeTexture = null;
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
// quad // quad
glBegin(GL_QUADS); glBegin(GL_QUADS);
glVertex2d(q.left, q.bottom); glVertex2d(q.left, q.bottom);
@ -291,51 +291,51 @@ public class LwjglGraphicsModule extends GraphicsModule {
glVertex2d(q.left, q.top); glVertex2d(q.left, q.top);
glEnd(); glEnd();
} }
@Override @Override
public void quad(Rect rect, Color color) public void quad(Rect rect, Color color)
{ {
setColor(color); setColor(color);
quad(rect); quad(rect);
} }
@Override @Override
public void quad(Rect rect, Grad grad) public void quad(Rect rect, Grad grad)
{ {
final RectDigest r = rect.digest(); final RectDigest r = rect.digest();
// disable texture // disable texture
if (activeTexture != null) { if (activeTexture != null) {
activeTexture = null; activeTexture = null;
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
// quad // quad
glBegin(GL_QUADS); glBegin(GL_QUADS);
setColor(grad.leftBottom); setColor(grad.leftBottom);
glVertex2d(r.left, r.bottom); glVertex2d(r.left, r.bottom);
setColor(grad.rightBottom); setColor(grad.rightBottom);
glVertex2d(r.right, r.bottom); glVertex2d(r.right, r.bottom);
setColor(grad.rightTop); setColor(grad.rightTop);
glVertex2d(r.right, r.top); glVertex2d(r.right, r.top);
setColor(grad.leftTop); setColor(grad.leftTop);
glVertex2d(r.left, r.top); glVertex2d(r.left, r.top);
glEnd(); glEnd();
} }
@Override @Override
public void quad(Rect rect, TxQuad txquad) public void quad(Rect rect, TxQuad txquad)
{ {
quad(rect, txquad, RGB.WHITE); quad(rect, txquad, RGB.WHITE);
} }
@Override @Override
public void quad(Rect rect, TxQuad txquad, Color color) public void quad(Rect rect, TxQuad txquad, Color color)
{ {
@ -345,150 +345,150 @@ public class LwjglGraphicsModule extends GraphicsModule {
activeTexture = (SlickTexture) txquad.tx; activeTexture = (SlickTexture) txquad.tx;
activeTexture.bind(); activeTexture.bind();
} }
glBegin(GL_QUADS); glBegin(GL_QUADS);
setColor(color); setColor(color);
final RectDigest q = rect.digest(); final RectDigest q = rect.digest();
final RectDigest u = txquad.uvs.digest(); final RectDigest u = txquad.uvs.digest();
final double offs = 0.0001;// hack to avoid white stitching final double offs = 0.0001;// hack to avoid white stitching
double tL = u.left + offs, tR = u.right - offs, tT = u.top + offs, tB = u.bottom - offs; double tL = u.left + offs, tR = u.right - offs, tT = u.top + offs, tB = u.bottom - offs;
// handle flip // handle flip
if (txquad.isFlippedY()) { if (txquad.isFlippedY()) {
final double swap = tT; final double swap = tT;
tT = tB; tT = tB;
tB = swap; tB = swap;
} }
if (txquad.isFlippedX()) { if (txquad.isFlippedX()) {
final double swap = tL; final double swap = tL;
tL = tR; tL = tR;
tR = swap; tR = swap;
} }
final double w = activeTexture.getWidth01(); final double w = activeTexture.getWidth01();
final double h = activeTexture.getHeight01(); final double h = activeTexture.getHeight01();
// quad with texture // quad with texture
glTexCoord2d(tL * w, tB * h); glTexCoord2d(tL * w, tB * h);
glVertex2d(q.left, q.bottom); glVertex2d(q.left, q.bottom);
glTexCoord2d(tR * w, tB * h); glTexCoord2d(tR * w, tB * h);
glVertex2d(q.right, q.bottom); glVertex2d(q.right, q.bottom);
glTexCoord2d(tR * w, tT * h); glTexCoord2d(tR * w, tT * h);
glVertex2d(q.right, q.top); glVertex2d(q.right, q.top);
glTexCoord2d(tL * w, tT * h); glTexCoord2d(tL * w, tT * h);
glVertex2d(q.left, q.top); glVertex2d(q.left, q.top);
glEnd(); glEnd();
} }
@Override @Override
public void setupProjection() public void setupProjection()
{ {
// fix projection for changed size // fix projection for changed size
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
final int w = Display.getWidth(); final int w = Display.getWidth();
final int h = Display.getHeight(); final int h = Display.getHeight();
glViewport(0, 0, w, h); glViewport(0, 0, w, h);
glOrtho(0, w, h, 0, -1000, 1000); glOrtho(0, w, h, 0, -1000, 1000);
// back to modelview // back to modelview
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glClearDepth(1f); glClearDepth(1f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
@Override @Override
public DeferredTexture createTextureResource(String path) public DeferredTexture createTextureResource(String path)
{ {
return new SlickTexture(path); return new SlickTexture(path);
} }
@Override @Override
public DeferredFont createFontResource(String path) public DeferredFont createFontResource(String path)
{ {
return new LwjglFont(path); return new LwjglFont(path);
} }
@Override @Override
public void destroy() public void destroy()
{ {
Display.destroy(); Display.destroy();
} }
@Override @Override
public void setTargetFps(int fps) public void setTargetFps(int fps)
{ {
this.targetFps = fps; this.targetFps = fps;
} }
@Override @Override
public void setFullscreen(boolean fs) public void setFullscreen(boolean fs)
{ {
fullscreenSetRequested = true; fullscreenSetRequested = true;
fullscreenSetState = fs; fullscreenSetState = fs;
} }
@Override @Override
public void switchFullscreen() public void switchFullscreen()
{ {
fullscreenToggleRequested = true; fullscreenToggleRequested = true;
} }
@Override @Override
public boolean isFullscreen() public boolean isFullscreen()
{ {
return Display.isFullscreen(); return Display.isFullscreen();
} }
private void doToggleFullscreen() private void doToggleFullscreen()
{ {
doSetFullscreen(!Display.isFullscreen()); doSetFullscreen(!Display.isFullscreen());
} }
private void doSetFullscreen(boolean fs) private void doSetFullscreen(boolean fs)
{ {
try { try {
if (Display.isFullscreen() == fs) return; // no work
if (Display.isFullscreen() == fs) return; // no work
if (fs) { if (fs) {
Log.f3("Entering fullscreen."); Log.f3("Entering fullscreen.");
// save window resize // save window resize
windowDisplayMode = new DisplayMode(Display.getWidth(), Display.getHeight()); windowDisplayMode = new DisplayMode(Display.getWidth(), Display.getHeight());
Display.setDisplayMode(Display.getDesktopDisplayMode()); Display.setDisplayMode(Display.getDesktopDisplayMode());
Display.setFullscreen(true); Display.setFullscreen(true);
Display.update(); Display.update();
@ -497,9 +497,9 @@ public class LwjglGraphicsModule extends GraphicsModule {
Display.setDisplayMode(windowDisplayMode); Display.setDisplayMode(windowDisplayMode);
Display.update(); Display.update();
} }
App.bus().send(new ViewportChangeEvent(getSize())); App.bus().send(new ViewportChangeEvent(getSize()));
} catch (final Throwable t) { } catch (final Throwable t) {
Log.e("Failed to change fullscreen mode.", t); Log.e("Failed to change fullscreen mode.", t);
try { try {
@ -510,8 +510,8 @@ public class LwjglGraphicsModule extends GraphicsModule {
} }
} }
} }
@Override @Override
public Screenshot takeScreenshot() public Screenshot takeScreenshot()
{ {
@ -521,13 +521,13 @@ public class LwjglGraphicsModule extends GraphicsModule {
final int bpp = 4; final int bpp = 4;
final ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp); final ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
final AwtScreenshot sc = new AwtScreenshot(width, height, bpp, buffer); final AwtScreenshot sc = new AwtScreenshot(width, height, bpp, buffer);
return sc; return sc;
} }
@Override @Override
public void beginFrame() public void beginFrame()
{ {
@ -535,31 +535,31 @@ public class LwjglGraphicsModule extends GraphicsModule {
if (Display.wasResized()) { if (Display.wasResized()) {
App.bus().send(new ViewportChangeEvent(getSize())); App.bus().send(new ViewportChangeEvent(getSize()));
} }
if (fullscreenToggleRequested) { if (fullscreenToggleRequested) {
fullscreenToggleRequested = false; fullscreenToggleRequested = false;
doToggleFullscreen(); doToggleFullscreen();
} }
if (fullscreenSetRequested) { if (fullscreenSetRequested) {
fullscreenSetRequested = false; fullscreenSetRequested = false;
doSetFullscreen(fullscreenSetState); doSetFullscreen(fullscreenSetState);
} }
glLoadIdentity(); glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
fpsMeter.frame(); fpsMeter.frame();
} }
@Override @Override
public void endFrame() public void endFrame()
{ {
Display.update(false); // don't poll input devices Display.update(false); // don't poll input devices
Display.sync(targetFps); Display.sync(targetFps);
} }
@Override @Override
public void setSize(int width, int height) public void setSize(int width, int height)
{ {
@ -569,68 +569,68 @@ public class LwjglGraphicsModule extends GraphicsModule {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Override @Override
public void setTitle(String title) public void setTitle(String title)
{ {
Display.setTitle(title); Display.setTitle(title);
} }
@Override @Override
public void setVSync(boolean vsync) public void setVSync(boolean vsync)
{ {
Display.setVSyncEnabled(vsync); Display.setVSyncEnabled(vsync);
} }
@Override @Override
public void setResizable(boolean resizable) public void setResizable(boolean resizable)
{ {
Display.setResizable(resizable); Display.setResizable(resizable);
} }
@Override @Override
public Rect getRect() public Rect getRect()
{ {
return rect; return rect;
} }
@Override @Override
public long getFps() public long getFps()
{ {
return fpsMeter.getFPS(); return fpsMeter.getFPS();
} }
@Override @Override
public Vect getCenter() public Vect getCenter()
{ {
return rect.center(); return rect.center();
} }
@Override @Override
public int getWidth() public int getWidth()
{ {
return Display.getWidth(); return Display.getWidth();
} }
@Override @Override
public int getHeight() public int getHeight()
{ {
return Display.getHeight(); return Display.getHeight();
} }
@Override @Override
public Vect getSize() public Vect getSize()
{ {
return screenSize; return screenSize;
} }
} }

@ -23,12 +23,12 @@ import org.newdawn.slick.opengl.TextureLoader;
@Alias(name = "Texture") @Alias(name = "Texture")
@MustLoadInRenderingContext @MustLoadInRenderingContext
public class SlickTexture extends DeferredTexture { public class SlickTexture extends DeferredTexture {
private org.newdawn.slick.opengl.Texture backingTexture; private org.newdawn.slick.opengl.Texture backingTexture;
private boolean alpha; private boolean alpha;
private boolean alphal; private boolean alphal;
/** /**
* @param resourcePath resource path * @param resourcePath resource path
*/ */
@ -36,14 +36,14 @@ public class SlickTexture extends DeferredTexture {
{ {
super(resourcePath); super(resourcePath);
} }
@Override @Override
protected synchronized void loadResource(String path) protected synchronized void loadResource(String path)
{ {
try { try {
final String ext = FileUtil.getExtension(path).toUpperCase(); final String ext = FileUtil.getExtension(path).toUpperCase();
final int filtering; final int filtering;
switch (filter) { switch (filter) {
case NEAREST: case NEAREST:
@ -55,49 +55,49 @@ public class SlickTexture extends DeferredTexture {
default: default:
throw new IllegalValueException("Unsupported filtering mode."); throw new IllegalValueException("Unsupported filtering mode.");
} }
final Texture texture = TextureLoader.getTexture(ext, FileUtil.getResource(path), false, filtering); final Texture texture = TextureLoader.getTexture(ext, FileUtil.getResource(path), false, filtering);
if (texture == null) { if (texture == null) {
Log.w("Texture " + path + " could not be loaded."); Log.w("Texture " + path + " could not be loaded.");
} }
backingTexture = texture; backingTexture = texture;
} catch (final IOException e) { } catch (final IOException e) {
Log.e("Loading of texture " + path + " failed.", e); Log.e("Loading of texture " + path + " failed.", e);
throw new RuntimeException("Could not load texture " + path + ".", e); throw new RuntimeException("Could not load texture " + path + ".", e);
} }
} }
@Override @Override
public boolean hasAlpha() public boolean hasAlpha()
{ {
if (!ensureLoaded()) return false; if (!ensureLoaded()) return false;
if (!alphal) { if (!alphal) {
alphal = true; alphal = true;
alpha = backingTexture.hasAlpha(); alpha = backingTexture.hasAlpha();
} }
return alpha; return alpha;
} }
/** /**
* Bind to GL context, applying the filters prescribed. * Bind to GL context, applying the filters prescribed.
*/ */
public void bind() public void bind()
{ {
if (!ensureLoaded()) return; if (!ensureLoaded()) return;
//GL11.glEnable(GL11.GL_TEXTURE_2D); //GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, getTextureID()); GL11.glBindTexture(GL11.GL_TEXTURE_2D, getTextureID());
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
final int wrapping; final int wrapping;
switch (wrap) { switch (wrap) {
case CLAMP: case CLAMP:
@ -109,10 +109,10 @@ public class SlickTexture extends DeferredTexture {
default: default:
throw new IllegalValueException("Unsupported wrapping mode."); throw new IllegalValueException("Unsupported wrapping mode.");
} }
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapping); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapping);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapping); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapping);
final int filtering; final int filtering;
switch (filter) { switch (filter) {
case NEAREST: case NEAREST:
@ -124,39 +124,39 @@ public class SlickTexture extends DeferredTexture {
default: default:
throw new IllegalValueException("Unsupported filtering mode."); throw new IllegalValueException("Unsupported filtering mode.");
} }
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filtering); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filtering);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filtering); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filtering);
} }
@Override @Override
public int getImageHeight() public int getImageHeight()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return backingTexture.getImageHeight(); return backingTexture.getImageHeight();
} }
@Override @Override
public int getImageWidth() public int getImageWidth()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return backingTexture.getImageWidth(); return backingTexture.getImageWidth();
} }
@Override @Override
public void destroy() public void destroy()
{ {
if (!isLoaded()) return; if (!isLoaded()) return;
backingTexture.release(); backingTexture.release();
} }
/** /**
* Get the height of the texture, 0..1.<br> * Get the height of the texture, 0..1.<br>
* *
@ -165,11 +165,11 @@ public class SlickTexture extends DeferredTexture {
public float getHeight01() public float getHeight01()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return backingTexture.getHeight(); return backingTexture.getHeight();
} }
/** /**
* Get the width of the texture, 0..1.<br> * Get the width of the texture, 0..1.<br>
* *
@ -178,18 +178,18 @@ public class SlickTexture extends DeferredTexture {
public float getWidth01() public float getWidth01()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return backingTexture.getWidth(); return backingTexture.getWidth();
} }
/** /**
* @return OpenGL texture ID * @return OpenGL texture ID
*/ */
public int getTextureID() public int getTextureID()
{ {
if (!ensureLoaded()) return -1; if (!ensureLoaded()) return -1;
return backingTexture.getTextureID(); return backingTexture.getTextureID();
} }
} }

@ -23,10 +23,10 @@ import mightypork.utils.math.constraints.vect.Vect;
@MustLoadInRenderingContext @MustLoadInRenderingContext
@Alias(name = "Font") @Alias(name = "Font")
public class LwjglFont extends DeferredFont { public class LwjglFont extends DeferredFont {
private IFont font = null; private IFont font = null;
/** /**
* A font from resource * A font from resource
* *
@ -36,18 +36,18 @@ public class LwjglFont extends DeferredFont {
{ {
super(resourcePath); super(resourcePath);
} }
@Override @Override
protected synchronized final void loadResource(String path) throws IOException protected synchronized final void loadResource(String path) throws IOException
{ {
final Font awtFont = getAwtFont(path, (float) size, style.numval); final Font awtFont = getAwtFont(path, (float) size, style.numval);
font = new LwjglTextureBackedFontImpl(awtFont, antialias, filter, chars); font = new LwjglTextureBackedFontImpl(awtFont, antialias, filter, chars);
font.setDiscardRatio(discardTop, discardBottom); font.setDiscardRatio(discardTop, discardBottom);
} }
/** /**
* Get a font for a resource path / name * Get a font for a resource path / name
* *
@ -60,9 +60,9 @@ public class LwjglFont extends DeferredFont {
protected Font getAwtFont(String resource, float size, int style) throws IOException protected Font getAwtFont(String resource, float size, int style) throws IOException
{ {
try(InputStream in = FileUtil.getResource(resource)) { try(InputStream in = FileUtil.getResource(resource)) {
Font awtFont = null;
Font awtFont = null;
if (in != null) { if (in != null) {
awtFont = Font.createFont(Font.TRUETYPE_FONT, in); awtFont = Font.createFont(Font.TRUETYPE_FONT, in);
awtFont = awtFont.deriveFont(size); awtFont = awtFont.deriveFont(size);
@ -70,14 +70,14 @@ public class LwjglFont extends DeferredFont {
} else { } else {
awtFont = new Font(/* font name */resource, style, (int) size); awtFont = new Font(/* font name */resource, style, (int) size);
} }
return awtFont; return awtFont;
} catch (final FontFormatException e) { } catch (final FontFormatException e) {
throw new IOException("Could not load font, bad format.", e); throw new IOException("Could not load font, bad format.", e);
} }
} }
/** /**
* Draw string * Draw string
* *
@ -88,11 +88,11 @@ public class LwjglFont extends DeferredFont {
public void draw(String str, Color color) public void draw(String str, Color color)
{ {
if (!ensureLoaded()) return; if (!ensureLoaded()) return;
font.draw(str, color); font.draw(str, color);
} }
/** /**
* Get size needed to render give string * Get size needed to render give string
* *
@ -103,11 +103,11 @@ public class LwjglFont extends DeferredFont {
public Vect getNeededSpace(String text) public Vect getNeededSpace(String text)
{ {
if (!ensureLoaded()) return Vect.ZERO; if (!ensureLoaded()) return Vect.ZERO;
return font.getNeededSpace(text); return font.getNeededSpace(text);
} }
/** /**
* @return font height * @return font height
*/ */
@ -115,27 +115,27 @@ public class LwjglFont extends DeferredFont {
public int getLineHeight() public int getLineHeight()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return font.getLineHeight(); return font.getLineHeight();
} }
@Override @Override
public int getFontSize() public int getFontSize()
{ {
if (!ensureLoaded()) return 0; if (!ensureLoaded()) return 0;
return font.getFontSize(); return font.getFontSize();
} }
@Override @Override
public int getWidth(String text) public int getWidth(String text)
{ {
return font.getWidth(text); return font.getWidth(text);
} }
@Override @Override
public void destroy() public void destroy()
{ {

@ -42,46 +42,46 @@ import org.newdawn.slick.opengl.GLUtils;
* @author Ondřej Hruška (MightyPork) * @author Ondřej Hruška (MightyPork)
*/ */
class LwjglTextureBackedFontImpl implements IFont { class LwjglTextureBackedFontImpl implements IFont {
private class CharTile { private class CharTile {
public int width; public int width;
public int height; public int height;
public int texPosX; public int texPosX;
public int texPosY; public int texPosY;
} }
/* char bank */ /* char bank */
private final Map<Character, CharTile> chars = new HashMap<>(255); private final Map<Character, CharTile> chars = new HashMap<>(255);
/* use antialiasing for rendering */ /* use antialiasing for rendering */
private final boolean antiAlias; private final boolean antiAlias;
/* loaded font size (requested) */ /* loaded font size (requested) */
private final int fontSize; private final int fontSize;
/* actual height of drawn glyphs */ /* actual height of drawn glyphs */
private int fontHeight; private int fontHeight;
/* texture id */ /* texture id */
private int textureID; private int textureID;
/* texture width */ /* texture width */
private int textureWidth; private int textureWidth;
/* texture height */ /* texture height */
private int textureHeight; private int textureHeight;
/* AWT font source */ /* AWT font source */
private final java.awt.Font font; private final java.awt.Font font;
private final FilterMode filter; private final FilterMode filter;
private double discardTop; private double discardTop;
private double discardBottom; private double discardBottom;
/** /**
* Make a font * Make a font
* *
@ -94,8 +94,8 @@ class LwjglTextureBackedFontImpl implements IFont {
{ {
this(font, antialias, filter, (" " + chars).toCharArray()); this(font, antialias, filter, (" " + chars).toCharArray());
} }
/** /**
* Make a font * Make a font
* *
@ -107,16 +107,16 @@ class LwjglTextureBackedFontImpl implements IFont {
public LwjglTextureBackedFontImpl(java.awt.Font font, boolean antialias, FilterMode filter, char[] chars) public LwjglTextureBackedFontImpl(java.awt.Font font, boolean antialias, FilterMode filter, char[] chars)
{ {
GLUtils.checkGLContext(); GLUtils.checkGLContext();
this.font = font; this.font = font;
this.filter = filter; this.filter = filter;
this.fontSize = font.getSize(); this.fontSize = font.getSize();
this.antiAlias = antialias; this.antiAlias = antialias;
createSet(chars); createSet(chars);
} }
/** /**
* Create a BufferedImage of the given character * Create a BufferedImage of the given character
* *
@ -128,43 +128,43 @@ class LwjglTextureBackedFontImpl implements IFont {
FontMetrics metrics; FontMetrics metrics;
BufferedImage img; BufferedImage img;
Graphics2D g; Graphics2D g;
// Create a temporary image to extract the character's size // Create a temporary image to extract the character's size
img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) img.getGraphics(); g = (Graphics2D) img.getGraphics();
if (antiAlias == true) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (antiAlias == true) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setFont(font); g.setFont(font);
metrics = g.getFontMetrics(); metrics = g.getFontMetrics();
final int charwidth = Math.max(1, metrics.charWidth(ch)); final int charwidth = Math.max(1, metrics.charWidth(ch));
final int charheight = Math.max(fontSize, metrics.getHeight()); final int charheight = Math.max(fontSize, metrics.getHeight());
// Create another image holding the character we are creating // Create another image holding the character we are creating
final BufferedImage fontImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB); final BufferedImage fontImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) fontImage.getGraphics(); g = (Graphics2D) fontImage.getGraphics();
if (antiAlias == true) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (antiAlias == true) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setFont(font); g.setFont(font);
g.setColor(java.awt.Color.WHITE); g.setColor(java.awt.Color.WHITE);
g.drawString(String.valueOf(ch), 0, metrics.getAscent()); g.drawString(String.valueOf(ch), 0, metrics.getAscent());
return fontImage; return fontImage;
} }
private void createSet(char[] charsToLoad) private void createSet(char[] charsToLoad)
{ {
try { try {
class LoadedGlyph { class LoadedGlyph {
public char c; public char c;
public BufferedImage image; public BufferedImage image;
public int width; public int width;
public int height; public int height;
public LoadedGlyph(char c, BufferedImage image) public LoadedGlyph(char c, BufferedImage image)
{ {
this.image = image; this.image = image;
@ -173,7 +173,7 @@ class LwjglTextureBackedFontImpl implements IFont {
this.height = image.getHeight(); this.height = image.getHeight();
} }
} }
final List<LoadedGlyph> glyphs = new ArrayList<>(); final List<LoadedGlyph> glyphs = new ArrayList<>();
final List<Character> loaded = new ArrayList<>(); final List<Character> loaded = new ArrayList<>();
for (final char ch : charsToLoad) { for (final char ch : charsToLoad) {
@ -182,38 +182,38 @@ class LwjglTextureBackedFontImpl implements IFont {
loaded.add(ch); loaded.add(ch);
} }
} }
int lineHeight = 0; int lineHeight = 0;
int beginX = 0, beginY = 0; int beginX = 0, beginY = 0;
int canvasW = 128, canvasH = 128; int canvasW = 128, canvasH = 128;
boolean needsLarger = false; boolean needsLarger = false;
// find smallest 2^x size for texture // find smallest 2^x size for texture
while (true) { while (true) {
needsLarger = false; needsLarger = false;
for (final LoadedGlyph glyph : glyphs) { for (final LoadedGlyph glyph : glyphs) {
if (beginX + glyph.width > canvasW) { if (beginX + glyph.width > canvasW) {
beginY += lineHeight; beginY += lineHeight;
lineHeight = 0; lineHeight = 0;
beginX = 0; beginX = 0;
} }
if (lineHeight < glyph.height) { if (lineHeight < glyph.height) {
lineHeight = glyph.height; lineHeight = glyph.height;
} }
if (beginY + lineHeight > canvasH) { if (beginY + lineHeight > canvasH) {
needsLarger = true; needsLarger = true;
break; break;
} }
// draw. // draw.
beginX += glyph.width; beginX += glyph.width;
} }
if (needsLarger) { if (needsLarger) {
canvasW *= 2; canvasW *= 2;
canvasH *= 2; canvasH *= 2;
@ -225,66 +225,66 @@ class LwjglTextureBackedFontImpl implements IFont {
break; break;
} }
} }
textureWidth = canvasW; textureWidth = canvasW;
textureHeight = canvasH; textureHeight = canvasH;
BufferedImage imag = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB); BufferedImage imag = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = (Graphics2D) imag.getGraphics(); final Graphics2D g = (Graphics2D) imag.getGraphics();
g.setColor(new java.awt.Color(0, 0, 0, 1)); g.setColor(new java.awt.Color(0, 0, 0, 1));
g.fillRect(0, 0, textureWidth, textureHeight); g.fillRect(0, 0, textureWidth, textureHeight);
int rowHeight = 0, posX = 0, posY = 0; int rowHeight = 0, posX = 0, posY = 0;
for (final LoadedGlyph glyph : glyphs) { for (final LoadedGlyph glyph : glyphs) {
final CharTile cht = new CharTile(); final CharTile cht = new CharTile();
cht.width = glyph.width; cht.width = glyph.width;
cht.height = glyph.height; cht.height = glyph.height;
if (posX + cht.width >= textureWidth) { if (posX + cht.width >= textureWidth) {
posX = 0; posX = 0;
posY += rowHeight; posY += rowHeight;
rowHeight = 0; rowHeight = 0;
} }
cht.texPosX = posX; cht.texPosX = posX;
cht.texPosY = posY; cht.texPosY = posY;
if (cht.height > fontHeight) { if (cht.height > fontHeight) {
fontHeight = cht.height; fontHeight = cht.height;
} }
if (cht.height > rowHeight) { if (cht.height > rowHeight) {
rowHeight = cht.height; rowHeight = cht.height;
} }
// Draw it here // Draw it here
g.drawImage(glyph.image, posX, posY, null); g.drawImage(glyph.image, posX, posY, null);
posX += cht.width; posX += cht.width;
chars.put(glyph.c, cht); chars.put(glyph.c, cht);
} }
textureID = loadImage(imag); textureID = loadImage(imag);
imag = null; imag = null;
} catch (final Throwable t) { } catch (final Throwable t) {
Log.e("Failed to load font.", t); Log.e("Failed to load font.", t);
} }
} }
private int loadImage(BufferedImage bufferedImage) private int loadImage(BufferedImage bufferedImage)
{ {
try { try {
final short width = (short) bufferedImage.getWidth(); final short width = (short) bufferedImage.getWidth();
final short height = (short) bufferedImage.getHeight(); final short height = (short) bufferedImage.getHeight();
final int bpp = (byte) bufferedImage.getColorModel().getPixelSize(); final int bpp = (byte) bufferedImage.getColorModel().getPixelSize();
ByteBuffer byteBuffer; ByteBuffer byteBuffer;
final DataBuffer db = bufferedImage.getData().getDataBuffer(); final DataBuffer db = bufferedImage.getData().getDataBuffer();
if (db instanceof DataBufferInt) { if (db instanceof DataBufferInt) {
@ -293,32 +293,32 @@ class LwjglTextureBackedFontImpl implements IFont {
for (int i = 0; i < intI.length; i++) { for (int i = 0; i < intI.length; i++) {
final byte b[] = intToByteArray(intI[i]); final byte b[] = intToByteArray(intI[i]);
final int newIndex = i * 4; final int newIndex = i * 4;
newI[newIndex] = b[1]; newI[newIndex] = b[1];
newI[newIndex + 1] = b[2]; newI[newIndex + 1] = b[2];
newI[newIndex + 2] = b[3]; newI[newIndex + 2] = b[3];
newI[newIndex + 3] = b[0]; newI[newIndex + 3] = b[0];
} }
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI); byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI);
} else { } else {
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()) byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder())
.put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData()); .put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
} }
byteBuffer.flip(); byteBuffer.flip();
final int internalFormat = GL_RGBA8, format = GL_RGBA; final int internalFormat = GL_RGBA8, format = GL_RGBA;
final IntBuffer textureId = BufferUtils.createIntBuffer(1); final IntBuffer textureId = BufferUtils.createIntBuffer(1);
glGenTextures(textureId); glGenTextures(textureId);
glBindTexture(GL_TEXTURE_2D, textureId.get(0)); glBindTexture(GL_TEXTURE_2D, textureId.get(0));
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
final int filtering; final int filtering;
switch (filter) { switch (filter) {
case NEAREST: case NEAREST:
@ -330,27 +330,27 @@ class LwjglTextureBackedFontImpl implements IFont {
default: default:
throw new IllegalValueException("Unsupported filtering mode."); throw new IllegalValueException("Unsupported filtering mode.");
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
GLU.gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, GL_UNSIGNED_BYTE, byteBuffer); GLU.gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, GL_UNSIGNED_BYTE, byteBuffer);
return textureId.get(0); return textureId.get(0);
} catch (final Throwable t) { } catch (final Throwable t) {
Log.e("Failed to load font.", t); Log.e("Failed to load font.", t);
} }
return -1; return -1;
} }
private static byte[] intToByteArray(int value) private static byte[] intToByteArray(int value)
{ {
return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value }; return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value };
} }
/** /**
* Get size needed to draw given string * Get size needed to draw given string
* *
@ -363,46 +363,46 @@ class LwjglTextureBackedFontImpl implements IFont {
int totalwidth = 0; int totalwidth = 0;
CharTile ch = null; CharTile ch = null;
for (int i = 0; i < text.length(); i++) { for (int i = 0; i < text.length(); i++) {
ch = chars.get(text.charAt(i)); ch = chars.get(text.charAt(i));
if (ch != null) totalwidth += ch.width; if (ch != null) totalwidth += ch.width;
} }
return totalwidth; return totalwidth;
} }
@Override @Override
public int getLineHeight() public int getLineHeight()
{ {
return (int) Math.round(fontHeight * ((1 - discardTop) - discardBottom)); return (int) Math.round(fontHeight * ((1 - discardTop) - discardBottom));
} }
@Override @Override
public int getFontSize() public int getFontSize()
{ {
return fontSize; return fontSize;
} }
@Override @Override
public void draw(String text, Color color) public void draw(String text, Color color)
{ {
GLUtils.checkGLContext(); GLUtils.checkGLContext();
// PUSH // PUSH
glPushAttrib(GL_ENABLE_BIT); glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureID); glBindTexture(GL_TEXTURE_2D, textureID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
final int filtering; final int filtering;
switch (filter) { switch (filter) {
case NEAREST: case NEAREST:
@ -414,82 +414,82 @@ class LwjglTextureBackedFontImpl implements IFont {
default: default:
throw new IllegalValueException("Unsupported filtering mode."); throw new IllegalValueException("Unsupported filtering mode.");
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
glColor4d(color.r(), color.g(), color.b(), color.a()); glColor4d(color.r(), color.g(), color.b(), color.a());
glBegin(GL_QUADS); glBegin(GL_QUADS);
CharTile chtx = null; CharTile chtx = null;
char charCurrent; char charCurrent;
int minx = 0; int minx = 0;
for (int i = 0; i < text.length(); i++) { for (int i = 0; i < text.length(); i++) {
charCurrent = text.charAt(i); charCurrent = text.charAt(i);
chtx = chars.get(charCurrent); chtx = chars.get(charCurrent);
if (chtx != null) { if (chtx != null) {
// draw quad // draw quad
final float txmin = chtx.texPosX; final float txmin = chtx.texPosX;
final float tymin = chtx.texPosY; final float tymin = chtx.texPosY;
final float draw_width = minx + chtx.width - minx; final float draw_width = minx + chtx.width - minx;
final float draw_height = chtx.height; final float draw_height = chtx.height;
final float drawy0 = (float) (0f - draw_height * discardTop); final float drawy0 = (float) (0f - draw_height * discardTop);
final float txmin01 = txmin / textureWidth; final float txmin01 = txmin / textureWidth;
final float tymin01 = tymin / textureHeight; final float tymin01 = tymin / textureHeight;
final float twidth01 = ((chtx.texPosX + chtx.width - txmin) / textureWidth); final float twidth01 = ((chtx.texPosX + chtx.width - txmin) / textureWidth);
final float theight01 = ((chtx.texPosY + chtx.height - tymin) / textureHeight); final float theight01 = ((chtx.texPosY + chtx.height - tymin) / textureHeight);
glTexCoord2f(txmin01, tymin01); glTexCoord2f(txmin01, tymin01);
glVertex2f(minx, drawy0); glVertex2f(minx, drawy0);
glTexCoord2f(txmin01, tymin01 + theight01); glTexCoord2f(txmin01, tymin01 + theight01);
glVertex2f(minx, drawy0 + draw_height); glVertex2f(minx, drawy0 + draw_height);
glTexCoord2f(txmin01 + twidth01, tymin01 + theight01); glTexCoord2f(txmin01 + twidth01, tymin01 + theight01);
glVertex2f(minx + draw_width, drawy0 + draw_height); glVertex2f(minx + draw_width, drawy0 + draw_height);
glTexCoord2f(txmin01 + twidth01, tymin01); glTexCoord2f(txmin01 + twidth01, tymin01);
glVertex2f(minx + draw_width, drawy0); glVertex2f(minx + draw_width, drawy0);
minx += chtx.width; minx += chtx.width;
} }
} }
glEnd(); glEnd();
// POP // POP
glPopAttrib(); glPopAttrib();
} }
@Override @Override
public VectConst getNeededSpace(String text) public VectConst getNeededSpace(String text)
{ {
return Vect.make(getWidth(text), getLineHeight()); return Vect.make(getWidth(text), getLineHeight());
} }
@Override @Override
public void setDiscardRatio(double top, double bottom) public void setDiscardRatio(double top, double bottom)
{ {
discardTop = top; discardTop = top;
discardBottom = bottom; discardBottom = bottom;
} }
@Override @Override
public double getTopDiscardRatio() public double getTopDiscardRatio()
{ {
return discardTop; return discardTop;
} }
@Override @Override
public double getBottomDiscardRatio() public double getBottomDiscardRatio()
{ {

Loading…
Cancel
Save