* Fix syntax errors due to JmeSystem/Platform changes

* Prevent stream closed exception when playing OGG music
 * Prevent UnsatisfiedLinkError when using audio effects on Mac
 * Add BitmapText caching to Nifty GUI. May improve FPS in guis with lots of text elements

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8237 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 14 years ago
parent 5ac90f46fa
commit 64c61c86e4
  1. 2
      engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
  2. 1
      engine/src/desktop/com/jme3/system/Natives.java
  3. 7
      engine/src/jogg/com/jme3/audio/plugins/OGGLoader.java
  4. 21
      engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java
  5. 3
      engine/src/lwjgl-ogl/com/jme3/system/lwjgl/LwjglCanvas.java
  6. 78
      engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
  7. 21
      engine/src/niftygui/com/jme3/niftygui/RenderDeviceJme.java
  8. 222
      engine/src/niftygui/com/jme3/niftygui/RenderFontJme.java

@ -178,7 +178,7 @@ public class OGLESShaderRenderer implements Renderer {
if (versionStr == null || versionStr.equals("")) { if (versionStr == null || versionStr.equals("")) {
glslVer = -1; glslVer = -1;
throw new UnsupportedOperationException("GLSL and OpenGL2 is " throw new UnsupportedOperationException("GLSL and OpenGL2 is "
+ "required for the LWJGL " + "required for the OpenGL ES "
+ "renderer!"); + "renderer!");
} }

@ -31,7 +31,6 @@
*/ */
package com.jme3.system; package com.jme3.system;
import com.jme3.system.JmeSystem.Platform;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;

@ -245,7 +245,12 @@ public class OGGLoader implements AssetLoader {
InputStream in = null; InputStream in = null;
try { try {
in = info.openStream(); in = info.openStream();
return load(in, readStream, streamCache); AudioData data = load(in, readStream, streamCache);
if (data instanceof AudioStream){
// audio streams must remain open
in = null;
}
return data;
} finally { } finally {
if (in != null){ if (in != null){
in.close(); in.close();

@ -199,8 +199,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length); logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length);
supportEfx = ALC10.alcIsExtensionPresent(device, "ALC_EXT_EFX"); supportEfx = ALC10.alcIsExtensionPresent(device, "ALC_EXT_EFX");
logger.log(Level.FINER, "Audio EFX support: {0}", supportEfx);
if (supportEfx){ if (supportEfx){
ib.position(0).limit(1); ib.position(0).limit(1);
ALC10.alcGetInteger(device, EFX10.ALC_EFX_MAJOR_VERSION, ib); ALC10.alcGetInteger(device, EFX10.ALC_EFX_MAJOR_VERSION, ib);
@ -227,6 +225,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
// attach reverb effect to effect slot // attach reverb effect to effect slot
// EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx); // EFX10.alAuxiliaryEffectSloti(reverbFxSlot, EFX10.AL_EFFECTSLOT_EFFECT, reverbFx);
}else{
logger.log(Level.WARNING, "OpenAL EFX not available! Audio effects won't work.");
} }
} }
@ -348,7 +348,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance()); alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance());
break; break;
case ReverbFilter: case ReverbFilter:
if (!src.isPositional() || !src.isReverbEnabled()) if (!supportEfx || !src.isPositional() || !src.isReverbEnabled())
return; return;
int filter = EFX10.AL_FILTER_NULL; int filter = EFX10.AL_FILTER_NULL;
@ -362,7 +362,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, reverbFxSlot, 0, filter); AL11.alSource3i(id, EFX10.AL_AUXILIARY_SEND_FILTER, reverbFxSlot, 0, filter);
break; break;
case ReverbEnabled: case ReverbEnabled:
if (!src.isPositional()) if (!supportEfx || !src.isPositional())
return; return;
if (src.isReverbEnabled()){ if (src.isReverbEnabled()){
@ -418,6 +418,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
} }
break; break;
case DryFilter: case DryFilter:
if (!supportEfx)
return;
if (src.getDryFilter() != null){ if (src.getDryFilter() != null){
Filter f = src.getDryFilter(); Filter f = src.getDryFilter();
if (f.isUpdateNeeded()){ if (f.isUpdateNeeded()){
@ -459,7 +462,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance()); alSourcef(id, AL_REFERENCE_DISTANCE, src.getRefDistance());
alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE); alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
if (src.isReverbEnabled()){ if (src.isReverbEnabled() && supportEfx){
int filter = EFX10.AL_FILTER_NULL; int filter = EFX10.AL_FILTER_NULL;
if (src.getReverbFilter() != null){ if (src.getReverbFilter() != null){
Filter f = src.getReverbFilter(); Filter f = src.getReverbFilter();
@ -477,7 +480,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
alSource3f(id, AL_VELOCITY, 0,0,0); alSource3f(id, AL_VELOCITY, 0,0,0);
} }
if (src.getDryFilter() != null){ if (src.getDryFilter() != null && supportEfx){
Filter f = src.getDryFilter(); Filter f = src.getDryFilter();
if (f.isUpdateNeeded()){ if (f.isUpdateNeeded()){
updateFilter(f); updateFilter(f);
@ -589,7 +592,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
} }
} }
if (audioDisabled) if (audioDisabled || !supportEfx)
return; return;
EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DENSITY, env.getDensity()); EFX10.alEffectf(reverbFx, EFX10.AL_REVERB_DENSITY, env.getDensity());
@ -706,13 +709,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
alSourcei(sourceId, AL_BUFFER, 0); alSourcei(sourceId, AL_BUFFER, 0);
} }
if (src.getDryFilter() != null){ if (src.getDryFilter() != null && supportEfx){
// detach filter // detach filter
alSourcei(sourceId, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL); alSourcei(sourceId, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL);
} }
if (src.isPositional()){ if (src.isPositional()){
AudioNode pas = (AudioNode) src; AudioNode pas = (AudioNode) src;
if (pas.isReverbEnabled()) { if (pas.isReverbEnabled() && supportEfx) {
AL11.alSource3i(sourceId, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL); AL11.alSource3i(sourceId, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL);
} }
} }

@ -36,13 +36,12 @@ import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext; import com.jme3.system.JmeCanvasContext;
import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeContext.Type;
import com.jme3.system.JmeSystem; import com.jme3.system.JmeSystem;
import com.jme3.system.JmeSystem.Platform; import com.jme3.system.Platform;
import java.awt.Canvas; import java.awt.Canvas;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;

@ -55,6 +55,7 @@ public class InputSystemJme implements InputSystem, RawInputListener {
private InputManager inputManager; private InputManager inputManager;
private boolean isDragging = false, niftyOwnsDragging = false;
private boolean pressed = false; private boolean pressed = false;
private int buttonIndex; private int buttonIndex;
private int x, y; private int x, y;
@ -65,7 +66,6 @@ public class InputSystemJme implements InputSystem, RawInputListener {
private Nifty nifty; private Nifty nifty;
public InputSystemJme(InputManager inputManager){ public InputSystemJme(InputManager inputManager){
this.inputManager = inputManager; this.inputManager = inputManager;
} }
@ -86,53 +86,50 @@ public class InputSystemJme implements InputSystem, RawInputListener {
} }
public void beginInput(){ public void beginInput(){
} }
public void endInput(){ public void endInput(){
//requires nifty1.3
boolean result = nifty.update(); boolean result = nifty.update();
} }
public void onJoyAxisEvent(JoyAxisEvent evt) {
}
public void onJoyButtonEvent(JoyButtonEvent evt) {
}
private void onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic) { private void onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic) {
x = evt.getX(); x = evt.getX();
y = height - evt.getY(); y = height - evt.getY();
nic.processMouseEvent(x, y, evt.getDeltaWheel(), buttonIndex, pressed); nic.processMouseEvent(x, y, evt.getDeltaWheel(), buttonIndex, pressed);
//MouseInputEvent niftyEvt = new MouseInputEvent(x, y, pressed);
// if (nic.processMouseEvent(niftyEvt) /*|| nifty.getCurrentScreen().isMouseOverElement()*/){ // if (nic.processMouseEvent(niftyEvt) /*|| nifty.getCurrentScreen().isMouseOverElement()*/){
// Do not consume motion events // Do not consume motion events
//evt.setConsumed(); //evt.setConsumed();
// } // }
} }
public void onMouseMotionEvent(MouseMotionEvent evt) {
// Only forward the event if there's actual motion involved.
// No longer ignores mouse wheel
if (inputManager.isCursorVisible() && (evt.getDX() != 0 ||
evt.getDY() != 0 ||
evt.getDeltaWheel() != 0)){
inputQueue.add(evt);
}
}
private void onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic) { private void onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic) {
boolean wasPressed = pressed;
boolean forwardToNifty = true;
buttonIndex = evt.getButtonIndex(); buttonIndex = evt.getButtonIndex();
pressed = evt.isPressed(); pressed = evt.isPressed();
if (nic.processMouseEvent(x, y, 0, buttonIndex, pressed)){ // Mouse button raised. End dragging
evt.setConsumed(); if (wasPressed && !pressed){
if (!niftyOwnsDragging){
forwardToNifty = false;
}
isDragging = false;
niftyOwnsDragging = false;
} }
}
public void onMouseButtonEvent(MouseButtonEvent evt) { boolean consumed = false;
if (inputManager.isCursorVisible() && evt.getButtonIndex() >= 0 || evt.getButtonIndex() <= 2){ if (forwardToNifty){
inputQueue.add(evt); consumed = nic.processMouseEvent(x, y, 0, buttonIndex, pressed);
if (consumed){
evt.setConsumed();
}
}
// Mouse button pressed. Begin dragging
if (!wasPressed && pressed){
isDragging = true;
niftyOwnsDragging = consumed;
} }
} }
@ -155,10 +152,34 @@ public class InputSystemJme implements InputSystem, RawInputListener {
evt.setConsumed(); evt.setConsumed();
} }
} }
public void onMouseMotionEvent(MouseMotionEvent evt) {
// Only forward the event if there's actual motion involved.
if (inputManager.isCursorVisible() && (evt.getDX() != 0 ||
evt.getDY() != 0 ||
evt.getDeltaWheel() != 0)){
inputQueue.add(evt);
}
}
public void onMouseButtonEvent(MouseButtonEvent evt) {
if (inputManager.isCursorVisible() && evt.getButtonIndex() >= 0 || evt.getButtonIndex() <= 2){
inputQueue.add(evt);
}
}
public void onJoyAxisEvent(JoyAxisEvent evt) {
}
public void onJoyButtonEvent(JoyButtonEvent evt) {
}
public void onKeyEvent(KeyInputEvent evt) { public void onKeyEvent(KeyInputEvent evt) {
inputQueue.add(evt); inputQueue.add(evt);
} }
public void onTouchEvent(TouchEvent evt) {
}
public void forwardEvents(NiftyInputConsumer nic) { public void forwardEvents(NiftyInputConsumer nic) {
int queueSize = inputQueue.size(); int queueSize = inputQueue.size();
@ -177,6 +198,5 @@ public class InputSystemJme implements InputSystem, RawInputListener {
inputQueue.clear(); inputQueue.clear();
} }
public void onTouchEvent(TouchEvent evt) {
}
} }

@ -53,12 +53,17 @@ import de.lessvoid.nifty.spi.render.*;
import de.lessvoid.nifty.tools.Color; import de.lessvoid.nifty.tools.Color;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
public class RenderDeviceJme implements RenderDevice { public class RenderDeviceJme implements RenderDevice {
private NiftyJmeDisplay display; private NiftyJmeDisplay display;
private RenderManager rm; private RenderManager rm;
private Renderer r; private Renderer r;
private HashMap<String, BitmapText> textCacheLastFrame = new HashMap<String, BitmapText>();
private HashMap<String, BitmapText> textCacheCurrentFrame = new HashMap<String, BitmapText>();
private final Quad quad = new Quad(1, -1, true); private final Quad quad = new Quad(1, -1, true);
private final Geometry quadGeom = new Geometry("nifty-quad", quad); private final Geometry quadGeom = new Geometry("nifty-quad", quad);
@ -120,6 +125,10 @@ public class RenderDeviceJme implements RenderDevice {
} }
public void endFrame() { public void endFrame() {
HashMap<String, BitmapText> temp = textCacheLastFrame;
textCacheLastFrame = textCacheCurrentFrame;
textCacheCurrentFrame = temp;
textCacheCurrentFrame.clear();
} }
public int getWidth() { public int getWidth() {
@ -185,16 +194,20 @@ public class RenderDeviceJme implements RenderDevice {
return; return;
RenderFontJme jmeFont = (RenderFontJme) font; RenderFontJme jmeFont = (RenderFontJme) font;
BitmapText text = jmeFont.getText();
BitmapText text = textCacheLastFrame.get(str);
if (text == null) {
text = jmeFont.createText();
text.setText(str);
text.updateLogicalState(0);
}
textCacheCurrentFrame.put(str, text);
niftyMat.setColor("Color", convertColor(color, tempColor)); niftyMat.setColor("Color", convertColor(color, tempColor));
niftyMat.setBoolean("UseTex", true); niftyMat.setBoolean("UseTex", true);
niftyMat.getAdditionalRenderState().setBlendMode(convertBlend()); niftyMat.getAdditionalRenderState().setBlendMode(convertBlend());
text.setMaterial(niftyMat); text.setMaterial(niftyMat);
text.setText(str);
text.updateLogicalState(0);
float width = text.getLineWidth(); float width = text.getLineWidth();
float height = text.getLineHeight(); float height = text.getLineHeight();

@ -1,109 +1,113 @@
/* /*
* Copyright (c) 2009-2010 jMonkeyEngine * Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
* met: * met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.niftygui; package com.jme3.niftygui;
import com.jme3.font.BitmapFont; import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText; import com.jme3.font.BitmapText;
import de.lessvoid.nifty.spi.render.RenderFont; import de.lessvoid.nifty.spi.render.RenderFont;
public class RenderFontJme implements RenderFont { public class RenderFontJme implements RenderFont {
private NiftyJmeDisplay display; private NiftyJmeDisplay display;
private BitmapFont font; private BitmapFont font;
private BitmapText text; private BitmapText text;
private float actualSize; private float actualSize;
/** /**
* Initialize the font. * Initialize the font.
* @param name font filename * @param name font filename
*/ */
public RenderFontJme(String name, NiftyJmeDisplay display) { public RenderFontJme(String name, NiftyJmeDisplay display) {
this.display = display; this.display = display;
font = display.getAssetManager().loadFont(name); font = display.getAssetManager().loadFont(name);
if (font == null) { if (font == null) {
throw new RuntimeException( "Font not loaded:" + name ); throw new RuntimeException( "Font not loaded:" + name );
} }
text = new BitmapText(font); text = new BitmapText(font);
actualSize = font.getPreferredSize(); actualSize = font.getPreferredSize();
text.setSize(actualSize); text.setSize(actualSize);
} }
public BitmapText getText(){ public BitmapText createText() {
return text; return new BitmapText(font);
} }
/** public BitmapText getText(){
* get font height. return text;
* @return height }
*/
public int getHeight() { /**
return (int) text.getLineHeight(); * get font height.
} * @return height
*/
/** public int getHeight() {
* get font width of the given string. return (int) text.getLineHeight();
* @param text text }
* @return width of the given text for the current font
*/ /**
public int getWidth(final String str) { * get font width of the given string.
if (str.length() == 0) * @param text text
return 0; * @return width of the given text for the current font
*/
// Note: BitmapFont is now fixed to return the proper line width public int getWidth(final String str) {
// at least for now. The older commented out (by someone else, not me) if (str.length() == 0)
// code below is arguably 'more accurate' if BitmapFont gets return 0;
// buggy again. The issue is that the BitmapText and BitmapFont
// use a different algorithm for calculating size and both must // Note: BitmapFont is now fixed to return the proper line width
// be modified in sync. // at least for now. The older commented out (by someone else, not me)
int result = (int) font.getLineWidth(str); // code below is arguably 'more accurate' if BitmapFont gets
// text.setText(str); // buggy again. The issue is that the BitmapText and BitmapFont
// text.updateLogicalState(0); // use a different algorithm for calculating size and both must
// int result = (int) text.getLineWidth(); // be modified in sync.
int result = (int) font.getLineWidth(str);
return result; // text.setText(str);
} // text.updateLogicalState(0);
// int result = (int) text.getLineWidth();
/**
* Return the width of the given character including kerning information. return result;
* @param currentCharacter current character }
* @param nextCharacter next character
* @param size font size /**
* @return width of the character or null when no information for the character is available * Return the width of the given character including kerning information.
*/ * @param currentCharacter current character
public Integer getCharacterAdvance(final char currentCharacter, final char nextCharacter, final float size) { * @param nextCharacter next character
return Integer.valueOf( Math.round(font.getCharacterAdvance(currentCharacter, nextCharacter, size)) ); * @param size font size
} * @return width of the character or null when no information for the character is available
*/
public void dispose() { public Integer getCharacterAdvance(final char currentCharacter, final char nextCharacter, final float size) {
} return Integer.valueOf( Math.round(font.getCharacterAdvance(currentCharacter, nextCharacter, size)) );
} }
public void dispose() {
}
}

Loading…
Cancel
Save