|
@@ -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);
|