diff --git a/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java b/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
index 95cca4b3b..ce85507a1 100644
--- a/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
+++ b/engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
@@ -1708,50 +1708,59 @@ public class OGLESShaderRenderer implements Renderer {
}
}
- private void setupTextureParams(Texture tex){
+ /**
+ * setupTextureParams
sets the OpenGL context texture parameters
+ * @param tex the Texture to set the texture parameters from
+ */
+ private void setupTextureParams(Texture tex)
+ {
int target = convertTextureType(tex.getType());
// filter things
int minFilter = convertMinFilter(tex.getMinFilter());
int magFilter = convertMagFilter(tex.getMagFilter());
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MIN_FILTER, " + minFilter + ")");
+ if (verboseLogging)
+ logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MIN_FILTER, " + minFilter + ")");
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MIN_FILTER, minFilter);
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MAG_FILTER, " + magFilter + ")");
+ if (verboseLogging)
+ logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_MAG_FILTER, " + magFilter + ")");
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MAG_FILTER, magFilter);
+ /*
if (tex.getAnisotropicFilter() > 1){
-/*
+
if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic){
glTexParameterf(target,
EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT,
tex.getAnisotropicFilter());
}
-*/
+
}
+ */
// repeat modes
switch (tex.getType()){
case ThreeDimensional:
case CubeMap: // cubemaps use 3D coords
-// GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R)));
+ // GL_TEXTURE_WRAP_R is not available in api 8
+ //GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R)));
case TwoDimensional:
case TwoDimensionalArray:
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_T, " + convertWrapMode(tex.getWrap(WrapAxis.T)));
+ if (verboseLogging)
+ logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_T, " + convertWrapMode(tex.getWrap(WrapAxis.T)));
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T)));
+
// fall down here is intentional..
-// case OneDimensional:
+// case OneDimensional:
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_S, " + convertWrapMode(tex.getWrap(WrapAxis.S)));
+ if (verboseLogging)
+ logger.info("GLES20.glTexParameteri(" + target + ", GLES20.GL_TEXTURE_WRAP_S, " + convertWrapMode(tex.getWrap(WrapAxis.S)));
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S)));
break;
@@ -1773,13 +1782,20 @@ public class OGLESShaderRenderer implements Renderer {
*/
}
- public void updateTexImageData(Image img, Texture.Type type, boolean mips){
+ /**
+ * updateTexImageData
activates and binds the texture
+ * @param img
+ * @param type
+ * @param mips
+ */
+ public void updateTexImageData(Image img, Texture.Type type, boolean mips)
+ {
int texId = img.getId();
- if (texId == -1){
+ if (texId == -1)
+ {
// create texture
-
- if (verboseLogging)
- logger.info("GLES20.glGenTexture(1, buffer)");
+ if (verboseLogging)
+ logger.info("GLES20.glGenTexture(1, buffer)");
GLES20.glGenTextures(1, intBuf1);
texId = intBuf1.get(0);
@@ -1791,72 +1807,56 @@ public class OGLESShaderRenderer implements Renderer {
// bind texture
int target = convertTextureType(type);
- if (context.boundTextures[0] != img){
- if (context.boundTextureUnit != 0){
-
- if (verboseLogging)
- logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0)");
+ if (context.boundTextures[0] != img)
+ {
+ if (context.boundTextureUnit != 0)
+ {
+ if (verboseLogging)
+ logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0)");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
context.boundTextureUnit = 0;
}
- if (verboseLogging)
- logger.info("GLES20.glBindTexture(" + target + ", " + texId + ")");
+ if (verboseLogging)
+ logger.info("GLES20.glBindTexture(" + target + ", " + texId + ")");
GLES20.glBindTexture(target, texId);
context.boundTextures[0] = img;
}
- if (!img.hasMipmaps() && mips){
- // No pregenerated mips available,
- // generate from base level if required
-// if (!GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
-
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + "GLES11.GL_GENERATE_MIMAP, GLES20.GL_TRUE)");
- GLES20.glTexParameteri(target, GLES11.GL_GENERATE_MIPMAP, GLES20.GL_TRUE);
-// }
- }else{
-// glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0 );
- if (img.getMipMapSizes() != null){
-// GLES20.glTexParameteri(target, GLES11.GL_TEXTURE_MAX_LEVEL, img.getMipMapSizes().length );
+ if (target == GLES20.GL_TEXTURE_CUBE_MAP)
+ {
+ // Upload a cube map / sky box
+ @SuppressWarnings("unchecked")
+ List bmps = (List)img.getEfficentData();
+ if (bmps.size() != 6)
+ {
+ throw new UnsupportedOperationException("Invalid texture: " + img +
+ "Cubemap textures must contain 6 data units." );
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ TextureUtil.uploadTextureBitmap(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, bmps.get(i), false, powerOf2);
}
}
+ else
+ {
+ TextureUtil.uploadTexture(img, target, 0, 0, tdc, false, powerOf2);
+ if (verboseLogging)
+ logger.info("GLES20.glTexParameteri(" + target + "GLES11.GL_GENERATE_MIMAP, GLES20.GL_TRUE)");
- if (target == GLES20.GL_TEXTURE_CUBE_MAP){
- List data = img.getData();
- if (data.size() != 6){
- logger.log(Level.WARNING, "Invalid texture: {0}\n"
- + "Cubemap textures must contain 6 data units.", img);
- return;
- }
- for (int i = 0; i < 6; i++){
- TextureUtil.uploadTexture(img, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, tdc, true, powerOf2);
- }
- }/*else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){
- List data = img.getData();
- // -1 index specifies prepare data for 2D Array
- TextureUtil.uploadTexture(img, target, -1, 0, tdc);
- for (int i = 0; i < data.size(); i++){
- // upload each slice of 2D array in turn
- // this time with the appropriate index
- TextureUtil.uploadTexture(img, target, i, 0, tdc);
+ if (!img.hasMipmaps() && mips)
+ {
+ // No pregenerated mips available,
+ // generate from base level if required
+ if (verboseLogging)
+ logger.info("GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D)");
+ GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
}
- }*/else{
- TextureUtil.uploadTexture(img, target, 0, 0, tdc, true, powerOf2);
-
- if (verboseLogging)
- logger.info("GLES20.glTexParameteri(" + target + "GLES11.GL_GENERATE_MIMAP, GLES20.GL_TRUE)");
-
- GLES20.glTexParameteri(target, GLES11.GL_GENERATE_MIPMAP, GLES20.GL_TRUE);
- }
-
-// if (GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
-// glGenerateMipmapEXT(target);
-// }
+ }
img.clearUpdateNeeded();
}
@@ -1866,14 +1866,19 @@ public class OGLESShaderRenderer implements Renderer {
Image image = tex.getImage();
if (image.isUpdateNeeded())
{
+ /*
Bitmap bmp = (Bitmap)image.getEfficentData();
- // Check if the bitmap got recycled, can happen after wakeup/restart
- if ( bmp.isRecycled() )
+ if (bmp != null)
{
- // We need to reload the bitmap
- Texture textureReloaded = JmeSystem.newAssetManager().loadTexture((TextureKey)tex.getKey());
- image.setEfficentData( textureReloaded.getImage().getEfficentData());
+ // Check if the bitmap got recycled, can happen after wakeup/restart
+ if ( bmp.isRecycled() )
+ {
+ // We need to reload the bitmap
+ Texture textureReloaded = JmeSystem.newAssetManager().loadTexture((TextureKey)tex.getKey());
+ image.setEfficentData( textureReloaded.getImage().getEfficentData());
+ }
}
+ */
updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
}
diff --git a/engine/src/android/com/jme3/renderer/android/TextureUtil.java b/engine/src/android/com/jme3/renderer/android/TextureUtil.java
index f1eea426d..9e34d32cb 100644
--- a/engine/src/android/com/jme3/renderer/android/TextureUtil.java
+++ b/engine/src/android/com/jme3/renderer/android/TextureUtil.java
@@ -62,11 +62,21 @@ public class TextureUtil {
}
}
- private static void uploadTextureBitmap(Bitmap bitmap, boolean generateMips, boolean powerOf2){
- if (!powerOf2){
+ /**
+ * uploadTextureBitmap
uploads a native android bitmap
+ * @param target
+ * @param bitmap
+ * @param generateMips
+ * @param powerOf2
+ */
+ public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean generateMips, boolean powerOf2)
+ {
+ if (!powerOf2)
+ {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
- if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)){
+ if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height))
+ {
// scale to power of two
width = FastMath.nearestPowerOfTwo(width);
height = FastMath.nearestPowerOfTwo(height);
@@ -76,11 +86,14 @@ public class TextureUtil {
}
}
- if (generateMips){
+ if (generateMips)
+ {
buildMipmap(bitmap);
- }else{
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
- bitmap.recycle();
+ }
+ else
+ {
+ GLUtils.texImage2D(target, 0, bitmap, 0);
+ //bitmap.recycle();
}
}
@@ -95,8 +108,7 @@ public class TextureUtil {
if (img.getEfficentData() instanceof Bitmap){
Bitmap bitmap = (Bitmap) img.getEfficentData();
- uploadTextureBitmap(bitmap, generateMips, powerOf2);
-// img.setEfficentData(null);
+ uploadTextureBitmap(target, bitmap, generateMips, powerOf2);
return;
}
diff --git a/engine/src/android/com/jme3/util/android/AndroidSkyFactory.java b/engine/src/android/com/jme3/util/android/AndroidSkyFactory.java
new file mode 100644
index 000000000..7f11d3bd5
--- /dev/null
+++ b/engine/src/android/com/jme3/util/android/AndroidSkyFactory.java
@@ -0,0 +1,148 @@
+package com.jme3.util.android;
+
+import java.util.ArrayList;
+import android.graphics.Bitmap;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.asset.TextureKey;
+import com.jme3.material.Material;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.shape.Sphere;
+import com.jme3.texture.Image;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.TextureCubeMap;
+
+
+/**
+ * AndroidSkyFactory
creates a sky box spatial
+ * @author larynx, derived from SkyFactory and adapted for android
+ *
+ */
+public class AndroidSkyFactory
+{
+ private static final Sphere sphereMesh = new Sphere(10, 10, 101f, false, true);
+
+ public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap)
+ {
+ Geometry sky = new Geometry("Sky", sphereMesh);
+ sky.setQueueBucket(Bucket.Sky);
+ sky.setCullHint(Spatial.CullHint.Never);
+
+ Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
+ skyMat.setVector3("NormalScale", normalScale);
+ if (sphereMap)
+ {
+ skyMat.setBoolean("SphereMap", sphereMap);
+ }
+ else if (!(texture instanceof TextureCubeMap))
+ {
+ // make sure its a cubemap
+ Image img = texture.getImage();
+ texture = new TextureCubeMap();
+ texture.setImage(img);
+ }
+ skyMat.setTexture("Texture", texture);
+ sky.setMaterial(skyMat);
+
+ return sky;
+ }
+
+ private static void checkImage(Image image)
+ {
+ if (image.getWidth() != image.getHeight())
+ throw new IllegalArgumentException("Image width and height must be the same");
+
+ if (image.getMultiSamples() != 1)
+ throw new IllegalArgumentException("Multisample textures not allowed");
+ }
+
+ private static void checkImagesForCubeMap(Image ... images)
+ {
+ if (images.length == 1) return;
+
+ Format fmt = images[0].getFormat();
+ int width = images[0].getWidth();
+ int height = images[0].getHeight();
+
+ checkImage(images[0]);
+
+ for (int i = 1; i < images.length; i++)
+ {
+ Image image = images[i];
+ checkImage(images[i]);
+ if (image.getFormat() != fmt) throw new IllegalArgumentException("Images must have same format");
+ if (image.getWidth() != width) throw new IllegalArgumentException("Images must have same width");
+ if (image.getHeight() != height) throw new IllegalArgumentException("Images must have same height");
+ }
+ }
+
+ public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
+ Texture up, Texture down, Vector3f normalScale)
+ {
+ Geometry sky = new Geometry("Sky", sphereMesh);
+ sky.setQueueBucket(Bucket.Sky);
+ sky.setCullHint(Spatial.CullHint.Never);
+
+ Image westImg = west.getImage();
+ Image eastImg = east.getImage();
+ Image northImg = north.getImage();
+ Image southImg = south.getImage();
+ Image upImg = up.getImage();
+ Image downImg = down.getImage();
+
+ checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
+
+ Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
+
+ ArrayList arrayList = new ArrayList(6);
+
+ arrayList.add((Bitmap)westImg.getEfficentData());
+ arrayList.add((Bitmap)eastImg.getEfficentData());
+
+ arrayList.add((Bitmap)downImg.getEfficentData());
+ arrayList.add((Bitmap)upImg.getEfficentData());
+
+ arrayList.add((Bitmap)southImg.getEfficentData());
+ arrayList.add((Bitmap)northImg.getEfficentData());
+
+ cubeImage.setEfficentData(arrayList);
+
+ TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
+ cubeMap.setAnisotropicFilter(0);
+ cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
+ cubeMap.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
+ cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
+
+
+ Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
+ skyMat.setTexture("Texture", cubeMap);
+ skyMat.setVector3("NormalScale", normalScale);
+ sky.setMaterial(skyMat);
+
+ return sky;
+ }
+
+ public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
+ Texture up, Texture down)
+ {
+ return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
+ }
+
+ public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap)
+ {
+ return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
+ }
+
+ public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap)
+ {
+ TextureKey key = new TextureKey(textureName, true);
+ key.setGenerateMips(true);
+ key.setAsCube(!sphereMap);
+ Texture tex = assetManager.loadTexture(key);
+ return createSky(assetManager, tex, sphereMap);
+ }
+}
\ No newline at end of file