Hi,
I added support for Texture2DArray, should work on all GPUs with OpenGL>=3
A testcaseA small, self-contained application class that shows the effects of a problem. It should use only default assets so that it can be posted in the forum in code tags and run as-is by the developers. is included in the diff:
Index: src/test/jme3test/texture/TestTextureArray.java
===================================================================
--- src/test/jme3test/texture/TestTextureArray.java (revision 0)
+++ src/test/jme3test/texture/TestTextureArray.java (revision 0)
@@ -0,0 +1,78 @@
+package jme3test.texture;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.texture.Image;
+import com.jme3.texture.Texture;
+import com.jme3.texture.TextureArray;
+import com.jme3.util.BufferUtils;
+
+public class TestTextureArray extends SimpleApplication
+{
+
+ @Override
+ public void simpleInitApp()
+ {
+ Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedArray.j3md");
+
+ Texture tex1 = assetManager.loadTexture( "Textures/Terrain/Pond/Pond.png");
+ Texture tex2 = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
+ List<Image> images = new ArrayList<Image>();
+ images.add(tex1.getImage());
+ images.add(tex2.getImage());
+ TextureArray tex3 = new TextureArray(images);
+ mat.setTexture("ColorMap", tex3);
+
+ Mesh m = new Mesh();
+ Vector3f[] vertices = new Vector3f[8];
+ vertices[0] = new Vector3f(0, 0, 0);
+ vertices[1] = new Vector3f(3, 0, 0);
+ vertices[2] = new Vector3f(0, 3, 0);
+ vertices[3] = new Vector3f(3, 3, 0);
+
+ vertices[4] = new Vector3f(3, 0, 0);
+ vertices[5] = new Vector3f(6, 0, 0);
+ vertices[6] = new Vector3f(3, 3, 0);
+ vertices[7] = new Vector3f(6, 3, 0);
+
+ Vector3f[] texCoord = new Vector3f[8];
+ texCoord[0] = new Vector3f(0, 0, 0);
+ texCoord[1] = new Vector3f(1, 0, 0);
+ texCoord[2] = new Vector3f(0, 1, 0);
+ texCoord[3] = new Vector3f(1, 1, 0);
+
+ texCoord[4] = new Vector3f(0, 0, 1);
+ texCoord[5] = new Vector3f(1, 0, 1);
+ texCoord[6] = new Vector3f(0, 1, 1);
+ texCoord[7] = new Vector3f(1, 1, 1);
+
+ int[] indexes = { 2, 0, 1, 1, 3, 2 , 6, 4, 5, 5, 7, 6};
+
+ m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
+ m.setBuffer(Type.TexCoord, 3, BufferUtils.createFloatBuffer(texCoord));
+ m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
+ m.updateBound();
+
+ Geometry geom = new Geometry("Mesh", m);
+ geom.setMaterial(mat);
+ rootNode.attachChild(geom);
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ TestTextureArray app = new TestTextureArray();
+ app.start();
+ }
+
+}
Index: src/core/com/jme3/texture/TextureArray.java
===================================================================
--- src/core/com/jme3/texture/TextureArray.java (revision 0)
+++ src/core/com/jme3/texture/TextureArray.java (revision 0)
@@ -0,0 +1,111 @@
+package com.jme3.texture;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.scene.Node;
+
+public class TextureArray extends Texture
+{
+ private WrapMode wrapS = WrapMode.EdgeClamp;
+ private WrapMode wrapT = WrapMode.EdgeClamp;
+
+ public TextureArray()
+ {
+ super();
+ }
+
+ public TextureArray(List<Image> images)
+ {
+ super();
+ int width = images.get(0).getWidth();
+ int height = images.get(0).getHeight();
+ Image arrayImage = new Image(images.get(0).getFormat(), width, height,
+ null);
+
+ for (Image img : images)
+ {
+ if (img.getHeight() != height || img.getWidth() != width)
+ {
+ Logger.getLogger(TextureArray.class.getName()).log(
+ Level.WARNING,
+ "all images must have the same width/height");
+ continue;
+ }
+ arrayImage.addData(img.getData(0));
+ }
+ setImage(arrayImage);
+ }
+
+ @Override
+ public Texture createSimpleClone()
+ {
+ TextureArray clone = new TextureArray();
+ createSimpleClone(clone);
+ return clone;
+ }
+
+ @Override
+ public Texture createSimpleClone(Texture rVal)
+ {
+ rVal.setWrap(WrapAxis.S, wrapS);
+ rVal.setWrap(WrapAxis.T, wrapT);
+ return super.createSimpleClone(rVal);
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.TwoDimensionalArray;
+ }
+
+ @Override
+ public WrapMode getWrap(WrapAxis axis)
+ {
+ switch (axis)
+ {
+ case S:
+ return wrapS;
+ case T:
+ return wrapT;
+ default:
+ throw new IllegalArgumentException("invalid WrapAxis: " + axis);
+ }
+ }
+
+ @Override
+ public void setWrap(WrapAxis axis, WrapMode mode)
+ {
+ if (mode == null)
+ {
+ throw new IllegalArgumentException("mode can not be null.");
+ } else if (axis == null)
+ {
+ throw new IllegalArgumentException("axis can not be null.");
+ }
+ switch (axis)
+ {
+ case S:
+ this.wrapS = mode;
+ break;
+ case T:
+ this.wrapT = mode;
+ break;
+ default:
+ throw new IllegalArgumentException("Not applicable for 2D textures");
+ }
+ }
+
+ @Override
+ public void setWrap(WrapMode mode)
+ {
+ if (mode == null)
+ {
+ throw new IllegalArgumentException("mode can not be null.");
+ }
+ this.wrapS = mode;
+ this.wrapT = mode;
+ }
+
+}
Index: src/lwjgl-ogl/com/jme3/renderer/lwjgl/TextureUtil.java
===================================================================
--- src/lwjgl-ogl/com/jme3/renderer/lwjgl/TextureUtil.java (revision 7731)
+++ src/lwjgl-ogl/com/jme3/renderer/lwjgl/TextureUtil.java (working copy)
@@ -474,7 +474,7 @@
border,
format,
dataType,
- 0);
+ data);
}else{
glTexSubImage3D(target,
i, // level
Index: src/core-data/Common/MatDefs/Misc/UnshadedArray.j3md
===================================================================
--- src/core-data/Common/MatDefs/Misc/UnshadedArray.j3md (revision 0)
+++ src/core-data/Common/MatDefs/Misc/UnshadedArray.j3md (revision 0)
@@ -0,0 +1,70 @@
+MaterialDef Unshaded {
+
+ MaterialParameters {
+ TextureArray ColorMap
+ Texture2D LightMap
+ Color Color : Color
+ Boolean VertexColor
+ Boolean SeparateTexCoord
+
+ // Texture of the glowing parts of the material
+ Texture2D GlowMap
+ // The glow color of the object
+ Color GlowColor
+ }
+
+ Technique {
+ VertexShader GLSL100: Common/MatDefs/Misc/UnshadedArray.vert
+ FragmentShader GLSL100: Common/MatDefs/Misc/UnshadedArray.frag
+
+ WorldParameters {
+ WorldViewProjectionMatrix
+ }
+
+ Defines {
+ SEPARATE_TEXCOORD : SeparateTexCoord
+ HAS_COLORMAP : ColorMap
+ HAS_LIGHTMAP : LightMap
+ HAS_VERTEXCOLOR : VertexColor
+ HAS_COLOR : Color
+ }
+ }
+
+ Technique PreNormalPass {
+
+ VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert
+ FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag
+
+ WorldParameters {
+ WorldViewProjectionMatrix
+ WorldViewMatrix
+ NormalMatrix
+ }
+
+ RenderState {
+
+ }
+
+ }
+
+
+ Technique Glow {
+
+ VertexShader GLSL100: Common/MatDefs/Misc/UnshadedArray.vert
+ FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag
+
+ WorldParameters {
+ WorldViewProjectionMatrix
+ }
+
+ Defines {
+ HAS_GLOWMAP : GlowMap
+ HAS_GLOWCOLOR : GlowColor
+ HAS_COLORMAP // Must be passed so that Unshaded.vert exports texCoord.
+ }
+ }
+
+ Technique FixedFunc {
+ }
+
+}
Index: src/core-data/Common/MatDefs/Misc/UnshadedArray.frag
===================================================================
--- src/core-data/Common/MatDefs/Misc/UnshadedArray.frag (revision 0)
+++ src/core-data/Common/MatDefs/Misc/UnshadedArray.frag (revision 0)
@@ -0,0 +1,50 @@
+uniform vec4 m_Color;
+
+#if defined(HAS_GLOWMAP) || defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
+ #define NEED_TEXCOORD1
+#endif
+
+#ifdef HAS_COLORMAP
+ uniform sampler2DArray m_ColorMap;
+#endif
+
+#ifdef NEED_TEXCOORD1
+ varying vec3 texCoord1;
+#endif
+
+#ifdef HAS_LIGHTMAP
+ uniform sampler2D m_LightMap;
+ #ifdef SEPERATE_TEXCOORD
+ varying vec3 texCoord2;
+ #endif
+#endif
+
+#ifdef HAS_VERTEXCOLOR
+ varying vec4 vertColor;
+#endif
+
+void main(){
+ vec4 color = vec4(1.0);
+
+ #ifdef HAS_COLORMAP
+ color *= texture2DArray(m_ColorMap, texCoord1);
+ #endif
+
+ #ifdef HAS_VERTEXCOLOR
+ color *= vertColor;
+ #endif
+
+ #ifdef HAS_COLOR
+ color *= m_Color;
+ #endif
+
+ #ifdef HAS_LIGHTMAP
+ #ifdef SEPARATE_TEXCOORD
+ color.rgb *= texture2D(m_LightMap, texCoord2).rgb;
+ #else
+ color.rgb *= texture2D(m_LightMap, texCoord1).rgb;
+ #endif
+ #endif
+
+ gl_FragColor = color;
+}
Index: src/core-data/Common/MatDefs/Misc/UnshadedArray.vert
===================================================================
--- src/core-data/Common/MatDefs/Misc/UnshadedArray.vert (revision 0)
+++ src/core-data/Common/MatDefs/Misc/UnshadedArray.vert (revision 0)
@@ -0,0 +1,37 @@
+uniform mat4 g_WorldViewProjectionMatrix;
+attribute vec3 inPosition;
+
+#if defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD))
+ #define NEED_TEXCOORD1
+#endif
+
+#ifdef NEED_TEXCOORD1
+ attribute vec3 inTexCoord;
+ varying vec3 texCoord1;
+#endif
+
+#ifdef SEPARATE_TEXCOORD
+ attribute vec3 inTexCoord2;
+ varying vec3 texCoord2;
+#endif
+
+#ifdef HAS_VERTEXCOLOR
+ attribute vec4 inColor;
+ varying vec4 vertColor;
+#endif
+
+void main(){
+ #ifdef NEED_TEXCOORD1
+ texCoord1 = inTexCoord;
+ #endif
+
+ #ifdef SEPARATE_TEXCOORD
+ texCoord2 = inTexCoord2;
+ #endif
+
+ #ifdef HAS_VERTEXCOLOR
+ vertColor = inColor;
+ #endif
+
+ gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
+}