Merge pull request #213 from void256/master

feature: Update Nifty GUI to version 1.4.1
experimental
normen 10 years ago
commit 0e6bc92d19
  1. 13
      jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java
  2. 6
      jme3-niftygui/build.gradle
  3. 4
      jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiEvent.java
  4. 4
      jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiTrack.java
  5. 3
      jme3-niftygui/src/main/java/com/jme3/niftygui/InputSystemJme.java
  6. 137
      jme3-niftygui/src/main/java/com/jme3/niftygui/JmeBatchRenderBackend.java
  7. 107
      jme3-niftygui/src/main/java/com/jme3/niftygui/NiftyJmeDisplay.java
  8. 11
      jme3-niftygui/src/main/java/com/jme3/niftygui/RenderDeviceJme.java

@ -52,6 +52,7 @@ public class TestNiftyGui extends SimpleApplication implements ScreenController
app.start();
}
@Override
public void simpleInitApp() {
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom = new Geometry("Box", b);
@ -60,10 +61,11 @@ public class TestNiftyGui extends SimpleApplication implements ScreenController
geom.setMaterial(mat);
rootNode.attachChild(geom);
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
inputManager,
audioRenderer,
guiViewPort);
NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
assetManager,
inputManager,
audioRenderer,
guiViewPort);
nifty = niftyDisplay.getNifty();
nifty.fromXml("Interface/Nifty/HelloJme.xml", "start", this);
@ -76,14 +78,17 @@ public class TestNiftyGui extends SimpleApplication implements ScreenController
inputManager.setCursorVisible(true);
}
@Override
public void bind(Nifty nifty, Screen screen) {
System.out.println("bind( " + screen.getScreenId() + ")");
}
@Override
public void onStartScreen() {
System.out.println("onStartScreen");
}
@Override
public void onEndScreen() {
System.out.println("onEndScreen");
}

@ -10,7 +10,7 @@ repositories {
dependencies {
compile project(':jme3-core')
compile 'lessvoid:nifty:1.3.3'
compile 'lessvoid:nifty-default-controls:1.3.3'
compile 'lessvoid:nifty-style-black:1.3.3'
compile 'lessvoid:nifty:1.4.1'
compile 'lessvoid:nifty-default-controls:1.4.1'
compile 'lessvoid:nifty-style-black:1.4.1'
}

@ -37,7 +37,6 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.NullScreen;
import java.io.IOException;
/**
@ -82,7 +81,8 @@ public class GuiEvent extends AbstractCinematicEvent {
}
@Override
public void onStop() { if (!(nifty.getCurrentScreen() instanceof NullScreen)) {
public void onStop() {
if (nifty.getCurrentScreen() != null) {
nifty.getCurrentScreen().endScreen(null);
}
}

@ -37,7 +37,6 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.NullScreen;
import java.io.IOException;
/**
@ -84,7 +83,8 @@ public class GuiTrack extends AbstractCinematicEvent {
}
@Override
public void onStop() { if (!(nifty.getCurrentScreen() instanceof NullScreen)) {
public void onStop() {
if (nifty.getCurrentScreen() != null) {
nifty.getCurrentScreen().endScreen(null);
}
}

@ -41,7 +41,6 @@ import com.jme3.system.JmeSystem;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.NiftyInputConsumer;
import de.lessvoid.nifty.controls.TextField;
import de.lessvoid.nifty.controls.nullobjects.TextFieldNull;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
import de.lessvoid.nifty.spi.input.InputSystem;
@ -310,7 +309,7 @@ public class InputSystemJme implements InputSystem, RawInputListener {
Element element = nifty.getCurrentScreen().getFocusHandler().getKeyboardFocusElement();
if (element != null) {
final TextField textField = element.getNiftyControl(TextField.class);
if (textField != null && !(textField instanceof TextFieldNull)) {
if (textField != null) {
Logger.getLogger(InputSystemJme.class.getName()).log(Level.FINE, "Current TextField: {0}", textField.getId());
String initialValue = textField.getText();
if (initialValue == null) {

@ -57,13 +57,15 @@ import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture2D;
import com.jme3.util.BufferUtils;
import de.lessvoid.nifty.batch.spi.BatchRenderBackend;
import de.lessvoid.nifty.render.batch.spi.BatchRenderBackend;
import de.lessvoid.nifty.render.BlendMode;
import de.lessvoid.nifty.spi.render.MouseCursor;
import de.lessvoid.nifty.tools.Color;
import de.lessvoid.nifty.tools.Factory;
import de.lessvoid.nifty.tools.ObjectPool;
import de.lessvoid.nifty.tools.ObjectPool.Factory;
import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
import java.util.HashMap;
import java.util.Map;
/**
* Nifty GUI BatchRenderBackend Implementation for jMonkeyEngine.
@ -82,18 +84,21 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
private RenderManager renderManager;
private NiftyJmeDisplay display;
private Texture2D textureAtlas;
private Map<Integer, Texture2D> textures = new HashMap<Integer, Texture2D>();
private int textureAtlasId = 1;
private Batch currentBatch;
private Matrix4f tempMat = new Matrix4f();
private ByteBuffer initialData;
// this is only used for debugging purpose and will make the removed textures filled with a color
private boolean fillRemovedTexture =
Boolean.getBoolean(System.getProperty(JmeBatchRenderBackend.class.getName() + ".fillRemovedTexture", "false"));
// please note: the old way to init this via a system property has been
// removed since it's now possible to configure it using the
// BatchRenderConfiguration class when you create the NiftyJmeDisplay instance
private boolean fillRemovedTexture = false;
public JmeBatchRenderBackend(final NiftyJmeDisplay display) {
this.display = display;
this.batchPool = new ObjectPool<Batch>(2, new Factory<Batch>() {
this.batchPool = new ObjectPool<Batch>(new Factory<Batch>() {
@Override
public Batch createNew() {
return new Batch();
@ -152,9 +157,18 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
@Override
public MouseCursor createMouseCursor(final String filename, final int hotspotX, final int hotspotY) throws IOException {
return new MouseCursor() {
public void dispose() {
}
};
@Override
public void dispose() {
}
@Override
public void enable() {
}
@Override
public void disable() {
}
};
}
@Override
@ -166,9 +180,9 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
}
@Override
public void createAtlasTexture(final int width, final int height) {
public int createTextureAtlas(final int width, final int height) {
try {
createAtlasTextureInternal(width, height);
int atlasId = addTexture(createAtlasTextureInternal(width, height));
// we just initialize a second buffer here that will replace the texture atlas image
initialData = BufferUtils.createByteBuffer(width*height*4);
@ -178,15 +192,18 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
initialData.put((byte) 0x00);
initialData.put((byte) 0xff);
}
return atlasId;
} catch (Exception e) {
log.log(Level.WARNING, e.getMessage(), e);
return 0; // TODO Nifty always expects this call to be successfull
// there currently is no way to return failure or something :/
}
}
@Override
public void clearAtlasTexture(final int width, final int height) {
initialData.rewind();
textureAtlas.getImage().setData(initialData);
public void clearTextureAtlas(final int atlasId) {
initialData.rewind();
getTextureAtlas(atlasId).getImage().setData(initialData);
}
@Override
@ -200,16 +217,41 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
}
@Override
public void addImageToTexture(final Image image, final int x, final int y) {
public Image loadImage(final ByteBuffer imageData, final int imageWidth, final int imageHeight) {
return new ImageImpl(new com.jme3.texture.Image(Format.RGBA8, imageWidth, imageHeight, imageData));
}
@Override
public void addImageToAtlas(final Image image, final int x, final int y, final int atlasTextureId) {
ImageImpl imageImpl = (ImageImpl) image;
imageImpl.modifyTexture(this, getTextureAtlas(atlasTextureId), x, y);
}
@Override
public int createNonAtlasTexture(final Image image) {
ImageImpl imageImpl = (ImageImpl) image;
imageImpl.modifyTexture(this, textureAtlas, x, y);
Texture2D texture = new Texture2D(imageImpl.image);
texture.setMinFilter(MinFilter.NearestNoMipMaps);
texture.setMagFilter(MagFilter.Nearest);
return addTexture(texture);
}
@Override
public void deleteNonAtlasTexture(final int textureId) {
textures.remove(textureId);
}
@Override
public void beginBatch(final BlendMode blendMode) {
public boolean existsNonAtlasTexture(final int textureId) {
return textures.containsKey(textureId);
}
@Override
public void beginBatch(final BlendMode blendMode, final int textureId) {
batches.add(batchPool.allocate());
currentBatch = batches.get(batches.size() - 1);
currentBatch.begin(blendMode);
currentBatch.begin(blendMode, getTextureAtlas(textureId));
}
@Override
@ -225,9 +267,10 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
final float textureX,
final float textureY,
final float textureWidth,
final float textureHeight) {
final float textureHeight,
final int textureId) {
if (!currentBatch.canAddQuad()) {
beginBatch(currentBatch.getBlendMode());
beginBatch(currentBatch.getBlendMode(), textureId);
}
currentBatch.addQuadInternal(x, y, width, height, color1, color2, color3, color4, textureX, textureY, textureWidth, textureHeight);
}
@ -242,7 +285,7 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
}
@Override
public void removeFromTexture(final Image image, final int x, final int y, final int w, final int h) {
public void removeImageFromAtlas(final Image image, final int x, final int y, final int w, final int h, final int atlasTextureId) {
// Since we clear the whole texture when we switch screens it's not really necessary to remove data from the
// texture atlas when individual textures are removed. If necessary this can be enabled with a system property.
if (!fillRemovedTexture) {
@ -258,24 +301,47 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
}
initialData.rewind();
modifyTexture(
textureAtlas,
getTextureAtlas(atlasTextureId),
new com.jme3.texture.Image(Format.RGBA8, image.getWidth(), image.getHeight(), initialData),
x,
y);
}
/**
* Whether or not to render textures with high quality settings. Usually, setting to true will result in slower
* performance, but nicer looking textures, and vice versa. How high quality textures are rendered versus low quality
* textures will vary depending on the {@link de.lessvoid.nifty.render.batch.spi.BatchRenderBackend} implementation.
*/
@Override
public void useHighQualityTextures(final boolean shouldUseHighQualityTextures) {
// TODO when true this should use something like linear filtering
// not sure right now how to tell jme about that ... might not be
// necessary to be set?
}
/**
* Whether or not to overwrite previously used atlas space with blank data. Setting to true will result in slower
* performance, but may be useful in debugging when visually inspecting the atlas, since there will not be portions
* of old images visible in currently unused atlas space.
*/
@Override
public void fillRemovedImagesInAtlas(final boolean shouldFill) {
fillRemovedTexture = shouldFill;
}
// internal implementations
private void createAtlasTextureInternal(final int width, final int height) throws Exception {
private Texture2D createAtlasTextureInternal(final int width, final int height) throws Exception {
ByteBuffer initialData = BufferUtils.createByteBuffer(width*height*4);
for (int i=0; i<width*height*4; i++) {
initialData.put((byte) 0x80);
initialData.put((byte) 0x00);
}
initialData.rewind();
textureAtlas = new Texture2D(new com.jme3.texture.Image(Format.RGBA8, width, height, initialData));
textureAtlas.setMinFilter(MinFilter.NearestNoMipMaps);
textureAtlas.setMagFilter(MagFilter.Nearest);
Texture2D texture = new Texture2D(new com.jme3.texture.Image(Format.RGBA8, width, height, initialData));
texture.setMinFilter(MinFilter.NearestNoMipMaps);
texture.setMagFilter(MagFilter.Nearest);
return texture;
}
private void modifyTexture(
@ -294,6 +360,16 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
renderer.modifyTexture(textureAtlas, image, x, y);
}
private Texture2D getTextureAtlas(final int atlasId) {
return textures.get(atlasId);
}
private int addTexture(final Texture2D texture) {
final int atlasId = textureAtlasId++;
textures.put(atlasId, texture);
return atlasId;
}
/**
* Simple BatchRenderBackend.Image implementation that will transport the dimensions of an image as well as the
* actual bytes from the loadImage() to the addImageToTexture() method.
@ -389,6 +465,7 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
// current blend mode
private BlendMode blendMode = BlendMode.BLEND;
private Texture2D texture;
private Material material;
public Batch() {
@ -416,8 +493,10 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
renderState.setDepthWrite(false);
}
public void begin(final BlendMode blendMode) {
public void begin(final BlendMode blendMode, final Texture2D texture) {
this.blendMode = blendMode;
this.texture = texture;
quadCount = 0;
globalVertexIndex = 0;
vertexPosBuffer.clear();
@ -449,7 +528,7 @@ public class JmeBatchRenderBackend implements BatchRenderBackend {
renderManager.setWorldMatrix(tempMat);
renderManager.setForcedRenderState(renderState);
material.setTexture("ColorMap", textureAtlas);
material.setTexture("ColorMap", texture);
mesh.updateCounts();
material.render(meshGeometry, renderManager);
renderManager.setForcedRenderState(null);

@ -49,7 +49,8 @@ import com.jme3.renderer.queue.RenderQueue;
import com.jme3.texture.FrameBuffer;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.batch.BatchRenderDevice;
import de.lessvoid.nifty.render.batch.BatchRenderConfiguration;
import de.lessvoid.nifty.render.batch.BatchRenderDevice;
import de.lessvoid.nifty.tools.TimeProvider;
import de.lessvoid.nifty.tools.resourceloader.ResourceLocation;
@ -92,6 +93,68 @@ public class NiftyJmeDisplay implements SceneProcessor {
public NiftyJmeDisplay() {
}
/**
* Create a new NiftyJmeDisplay for use with the Batched Nifty Renderer.
*
* Nifty will use texture atlases for rendering. Every graphical asset
* you're rendering through Nifty will be placed into a texture atlas. The
* goal is to render all Nifty components in a single (or at least very few)
* draw calls. This should speed up rendering quite a bit.
*
* This call will use a default BatchRenderConfiguration for Nifty.
* See the other method {@link #newNiftyJmeDisplay(com.jme3.asset.AssetManager, com.jme3.input.InputManager, com.jme3.audio.AudioRenderer, com.jme3.renderer.ViewPort, de.lessvoid.nifty.render.batch.BatchRenderConfiguration) }
* when you want to change the default BatchRenderConfiguration and provide
* your own.
*
* @param assetManager jME AssetManager
* @param inputManager jME InputManager
* @param audioRenderer jME AudioRenderer
* @param viewport Viewport to use
*/
public static NiftyJmeDisplay newNiftyJmeDisplay(
final AssetManager assetManager,
final InputManager inputManager,
final AudioRenderer audioRenderer,
final ViewPort viewport) {
return newNiftyJmeDisplay(
assetManager,
inputManager,
audioRenderer,
viewport,
new BatchRenderConfiguration());
}
/**
* Create a new NiftyJmeDisplay for use with the Batched Nifty Renderer.
*
* Nifty will use texture atlas for rendering. Every graphical asset you're
* rendering through Nifty will be placed into a texture atlas. The goal is
* to render all Nifty components in a single (or at least very few) draw
* calls. This should speed up rendering quite a bit.
*
* @param assetManager jME AssetManager
* @param inputManager jME InputManager
* @param audioRenderer jME AudioRenderer
* @param viewport Viewport to use
* @param batchRenderConfiguration the Nifty BatchRenderConfiguration that
* you can use to further configure batch rendering. If unsure you
* can simply use new BatchRenderConfiguration() in here for the
* default configuration which should give you good default values.
*/
public static NiftyJmeDisplay newNiftyJmeDisplay(
final AssetManager assetManager,
final InputManager inputManager,
final AudioRenderer audioRenderer,
final ViewPort viewport,
final BatchRenderConfiguration batchRenderConfiguration) {
return new NiftyJmeDisplay(
assetManager,
inputManager,
audioRenderer,
viewport,
batchRenderConfiguration);
}
/**
* Create a new NiftyJmeDisplay for use with the Batched Nifty Renderer (improved Nifty rendering performance).
*
@ -113,6 +176,10 @@ public class NiftyJmeDisplay implements SceneProcessor {
* @param viewport Viewport to use
* @param atlasWidth the width of the texture atlas Nifty uses to speed up rendering (2048 is a good value)
* @param atlasHeight the height of the texture atlas Nifty uses to speed up rendering (2048 is a good value)
*
* @deprecated use the static factory methods {@link #newNiftyJmeDisplay(com.jme3.asset.AssetManager, com.jme3.input.InputManager, com.jme3.audio.AudioRenderer, com.jme3.renderer.ViewPort) }
* or {@link #newNiftyJmeDisplay(com.jme3.asset.AssetManager, com.jme3.input.InputManager, com.jme3.audio.AudioRenderer, com.jme3.renderer.ViewPort, de.lessvoid.nifty.render.batch.BatchRenderConfiguration) }
* instead of this constructor.
*/
public NiftyJmeDisplay(
final AssetManager assetManager,
@ -120,14 +187,48 @@ public class NiftyJmeDisplay implements SceneProcessor {
final AudioRenderer audioRenderer,
final ViewPort viewport,
final int atlasWidth,
final int atlasHeight){
final int atlasHeight) {
// The code duplication in here really sucks - it's a copy of the
// private constructor below that takes a BatchRenderConfiguration as an
// additional parameter. This method should really be removed soon and
// users should simply call the new factory methods.
//
// For now I keep this constructor as-is but have marked it as deprecated
// to allow migration to the new way to instantiate this class.
initialize(assetManager, inputManager, audioRenderer, viewport);
this.renderDev = null;
this.batchRendererBackend = new JmeBatchRenderBackend(this);
BatchRenderConfiguration batchRenderConfiguration = new BatchRenderConfiguration();
batchRenderConfiguration.atlasWidth = atlasWidth;
batchRenderConfiguration.atlasHeight = atlasHeight;
nifty = new Nifty(
new BatchRenderDevice(batchRendererBackend, batchRenderConfiguration),
soundDev,
inputSys,
new TimeProvider());
inputSys.setNifty(nifty);
resourceLocation = new ResourceLocationJme();
nifty.getResourceLoader().removeAllResourceLocations();
nifty.getResourceLoader().addResourceLocation(resourceLocation);
}
private NiftyJmeDisplay(
final AssetManager assetManager,
final InputManager inputManager,
final AudioRenderer audioRenderer,
final ViewPort viewport,
final BatchRenderConfiguration batchRenderConfiguration) {
initialize(assetManager, inputManager, audioRenderer, viewport);
this.renderDev = null;
this.batchRendererBackend = new JmeBatchRenderBackend(this);
nifty = new Nifty(
new BatchRenderDevice(batchRendererBackend, atlasWidth, atlasHeight),
new BatchRenderDevice(batchRendererBackend, batchRenderConfiguration),
soundDev,
inputSys,
new TimeProvider());

@ -47,7 +47,6 @@ import com.jme3.scene.VertexBuffer.Usage;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture2D;
import com.jme3.util.BufferUtils;
import de.lessvoid.nifty.elements.render.TextRenderer.RenderFontNull;
import de.lessvoid.nifty.render.BlendMode;
import de.lessvoid.nifty.spi.render.MouseCursor;
import de.lessvoid.nifty.spi.render.RenderDevice;
@ -152,6 +151,14 @@ public class RenderDeviceJme implements RenderDevice {
return new MouseCursor() {
public void dispose() {
}
@Override
public void enable() {
}
@Override
public void disable() {
}
};
}
@ -223,7 +230,7 @@ public class RenderDeviceJme implements RenderDevice {
@Override
public void renderFont(RenderFont font, String str, int x, int y, Color color, float sizeX, float sizeY) {
if (str.length() == 0 || font instanceof RenderFontNull) {
if (str.length() == 0) {
return;
}

Loading…
Cancel
Save