- add pre-alpha ios renderer - fix FilterExplorer property updates - add support for blender 2.69 - prepare for new installer git-svn-id: https://jmonkeyengine.googlecode.com/svn/branches/3.0final@11043 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
4399db373b
commit
22c77b954c
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@ |
|||||||
|
package com.jme3.audio.android; |
||||||
|
|
||||||
|
import com.jme3.asset.AssetKey; |
||||||
|
import com.jme3.audio.AudioData; |
||||||
|
import com.jme3.audio.AudioRenderer; |
||||||
|
import com.jme3.util.NativeObject; |
||||||
|
|
||||||
|
public class AndroidAudioData extends AudioData { |
||||||
|
|
||||||
|
protected AssetKey<?> assetKey; |
||||||
|
protected float currentVolume = 0f; |
||||||
|
|
||||||
|
public AndroidAudioData(){ |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
protected AndroidAudioData(int id){ |
||||||
|
super(id); |
||||||
|
} |
||||||
|
|
||||||
|
public AssetKey<?> getAssetKey() { |
||||||
|
return assetKey; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAssetKey(AssetKey<?> assetKey) { |
||||||
|
this.assetKey = assetKey; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DataType getDataType() { |
||||||
|
return DataType.Buffer; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public float getDuration() { |
||||||
|
return 0; // TODO: ???
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void resetObject() { |
||||||
|
this.id = -1; |
||||||
|
setUpdateNeeded(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void deleteObject(Object rendererObject) { |
||||||
|
((AudioRenderer)rendererObject).deleteAudioData(this); |
||||||
|
} |
||||||
|
|
||||||
|
public float getCurrentVolume() { |
||||||
|
return currentVolume; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCurrentVolume(float currentVolume) { |
||||||
|
this.currentVolume = currentVolume; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public NativeObject createDestructableClone() { |
||||||
|
return new AndroidAudioData(id); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getUniqueId() { |
||||||
|
return ((long)OBJTYPE_AUDIOBUFFER << 32) | ((long)id); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.jme3.audio.android; |
||||||
|
|
||||||
|
import com.jme3.audio.AudioRenderer; |
||||||
|
|
||||||
|
/** |
||||||
|
* Android specific AudioRenderer interface that supports pausing and resuming |
||||||
|
* audio files when the app is minimized or placed in the background |
||||||
|
* |
||||||
|
* @author iwgeric |
||||||
|
*/ |
||||||
|
public interface AndroidAudioRenderer extends AudioRenderer { |
||||||
|
|
||||||
|
/** |
||||||
|
* Pauses all Playing audio. To be used when the app is placed in the |
||||||
|
* background. |
||||||
|
*/ |
||||||
|
public void pauseAll(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Resumes all Paused audio. To be used when the app is brought back to |
||||||
|
* the foreground. |
||||||
|
*/ |
||||||
|
public void resumeAll(); |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@ |
|||||||
|
package com.jme3.audio.plugins; |
||||||
|
|
||||||
|
import com.jme3.asset.AssetInfo; |
||||||
|
import com.jme3.asset.AssetLoader; |
||||||
|
import com.jme3.audio.android.AndroidAudioData; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>AndroidAudioLoader</code> will create an |
||||||
|
* {@link AndroidAudioData} object with the specified asset key. |
||||||
|
*/ |
||||||
|
public class AndroidAudioLoader implements AssetLoader { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object load(AssetInfo assetInfo) throws IOException { |
||||||
|
AndroidAudioData result = new AndroidAudioData(); |
||||||
|
result.setAssetKey(assetInfo.getKey()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,273 @@ |
|||||||
|
package com.jme3.renderer.ios; |
||||||
|
|
||||||
|
import com.jme3.renderer.RendererException; |
||||||
|
|
||||||
|
import java.nio.Buffer; |
||||||
|
import java.nio.FloatBuffer; |
||||||
|
import java.nio.IntBuffer; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
/** |
||||||
|
* The <code>iOS GLES interface</code> iOS alternative to Android's GLES20 class
|
||||||
|
* |
||||||
|
* @author Kostyantyn Hushchyn |
||||||
|
*/ |
||||||
|
public class JmeIosGLES { |
||||||
|
private static final Logger logger = Logger.getLogger(JmeIosGLES.class.getName()); |
||||||
|
|
||||||
|
private static boolean ENABLE_ERROR_CHECKING = true; |
||||||
|
|
||||||
|
public static final int GL_ALPHA = 0x00001906; |
||||||
|
public static final int GL_ALWAYS = 0x00000207; |
||||||
|
public static final int GL_ARRAY_BUFFER = 0x00008892; |
||||||
|
public static final int GL_BACK = 0x00000405; |
||||||
|
public static final int GL_BLEND = 0x00000be2; |
||||||
|
public static final int GL_BYTE = 0x00001400; |
||||||
|
public static final int GL_CLAMP_TO_EDGE = 0x0000812f; |
||||||
|
public static final int GL_COLOR_ATTACHMENT0 = 0x00008ce0; |
||||||
|
public static final int GL_COLOR_BUFFER_BIT = 0x00004000; |
||||||
|
public static final int GL_COMPILE_STATUS = 0x00008b81; |
||||||
|
public static final int GL_COMPRESSED_TEXTURE_FORMATS = 0x000086a3; |
||||||
|
public static final int GL_CULL_FACE = 0x00000b44; |
||||||
|
public static final int GL_DEPTH_ATTACHMENT = 0x00008d00; |
||||||
|
public static final int GL_DEPTH_BUFFER_BIT = 0x00000100; |
||||||
|
public static final int GL_DEPTH_COMPONENT = 0x00001902; |
||||||
|
public static final int GL_DEPTH_COMPONENT16 = 0x000081a5; |
||||||
|
public static final int GL_DEPTH_TEST = 0x00000b71; |
||||||
|
public static final int GL_DITHER = 0x00000bd0; |
||||||
|
public static final int GL_DST_COLOR = 0x00000306; |
||||||
|
public static final int GL_DYNAMIC_DRAW = 0x000088e8; |
||||||
|
public static final int GL_EQUAL = 0x00000202; |
||||||
|
public static final int GL_ELEMENT_ARRAY_BUFFER = 0x00008893; |
||||||
|
public static final int GL_EXTENSIONS = 0x00001f03; |
||||||
|
public static final int GL_FALSE = 0x00000000; |
||||||
|
public static final int GL_FLOAT = 0x00001406; |
||||||
|
public static final int GL_FRAGMENT_SHADER = 0x00008b30; |
||||||
|
public static final int GL_FRAMEBUFFER = 0x00008d40; |
||||||
|
public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x00008cd1; |
||||||
|
public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x00008cd0; |
||||||
|
public static final int GL_FRAMEBUFFER_COMPLETE = 0x00008cd5; |
||||||
|
public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x00008cd6; |
||||||
|
public static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x00008cd9; |
||||||
|
public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x00008cd7; |
||||||
|
public static final int GL_FRAMEBUFFER_UNSUPPORTED = 0x00008cdd; |
||||||
|
public static final int GL_FRONT = 0x00000404; |
||||||
|
public static final int GL_FRONT_AND_BACK = 0x00000408; |
||||||
|
public static final int GL_GEQUAL = 0x00000206; |
||||||
|
public static final int GL_GREATER = 0x00000204; |
||||||
|
public static final int GL_HIGH_FLOAT = 0x00008df2; |
||||||
|
public static final int GL_INFO_LOG_LENGTH = 0x00008b84; |
||||||
|
public static final int GL_INT = 0x00001404; |
||||||
|
public static final int GL_LEQUAL = 0x00000203; |
||||||
|
public static final int GL_LESS = 0x00000201; |
||||||
|
public static final int GL_LINEAR = 0x00002601; |
||||||
|
public static final int GL_LINEAR_MIPMAP_LINEAR = 0x00002703; |
||||||
|
public static final int GL_LINEAR_MIPMAP_NEAREST = 0x00002701; |
||||||
|
public static final int GL_LINES = 0x00000001; |
||||||
|
public static final int GL_LINE_LOOP = 0x00000002; |
||||||
|
public static final int GL_LINE_STRIP = 0x00000003; |
||||||
|
public static final int GL_LINK_STATUS = 0x00008b82; |
||||||
|
public static final int GL_LUMINANCE = 0x00001909; |
||||||
|
public static final int GL_LUMINANCE_ALPHA = 0x0000190a; |
||||||
|
public static final int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x0000851c; |
||||||
|
public static final int GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x00008dfd; |
||||||
|
public static final int GL_MAX_RENDERBUFFER_SIZE = 0x000084e8; |
||||||
|
public static final int GL_MAX_TEXTURE_IMAGE_UNITS = 0x00008872; |
||||||
|
public static final int GL_MAX_TEXTURE_SIZE = 0x00000d33; |
||||||
|
public static final int GL_MAX_VARYING_VECTORS = 0x00008dfc; |
||||||
|
public static final int GL_MAX_VERTEX_ATTRIBS = 0x00008869; |
||||||
|
public static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x00008b4c; |
||||||
|
public static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x00008dfb; |
||||||
|
public static final int GL_MIRRORED_REPEAT = 0x00008370; |
||||||
|
public static final int GL_NEAREST = 0x00002600; |
||||||
|
public static final int GL_NEAREST_MIPMAP_LINEAR = 0x00002702; |
||||||
|
public static final int GL_NEAREST_MIPMAP_NEAREST = 0x00002700; |
||||||
|
public static final int GL_NEVER = 0x00000200; |
||||||
|
public static final int GL_NONE = 0x00000000; |
||||||
|
public static final int GL_NOTEQUAL = 0x00000205; |
||||||
|
public static final int GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x000086a2; |
||||||
|
public static final int GL_ONE = 0x00000001; |
||||||
|
public static final int GL_ONE_MINUS_SRC_ALPHA = 0x00000303; |
||||||
|
public static final int GL_ONE_MINUS_SRC_COLOR = 0x00000301; |
||||||
|
public static final int GL_POINTS = 0x00000000; |
||||||
|
public static final int GL_POLYGON_OFFSET_FILL = 0x00008037; |
||||||
|
public static final int GL_RENDERBUFFER = 0x00008d41; |
||||||
|
public static final int GL_RENDERER = 0x00001f01; |
||||||
|
public static final int GL_REPEAT = 0x00002901; |
||||||
|
public static final int GL_RGB = 0x00001907; |
||||||
|
public static final int GL_RGB565 = 0x00008d62; |
||||||
|
public static final int GL_RGB5_A1 = 0x00008057; |
||||||
|
public static final int GL_RGBA = 0x00001908; |
||||||
|
public static final int GL_RGBA4 = 0x00008056; |
||||||
|
public static final int GL_SAMPLE_ALPHA_TO_COVERAGE = 0x0000809e; |
||||||
|
public static final int GL_SCISSOR_TEST = 0x00000c11; |
||||||
|
public static final int GL_SHADING_LANGUAGE_VERSION = 0x00008b8c; |
||||||
|
public static final int GL_SHORT = 0x00001402; |
||||||
|
public static final int GL_SRC_COLOR = 0x00000300; |
||||||
|
public static final int GL_SRC_ALPHA = 0x00000302; |
||||||
|
public static final int GL_STATIC_DRAW = 0x000088e4; |
||||||
|
public static final int GL_STENCIL_BUFFER_BIT = 0x00000400; |
||||||
|
public static final int GL_STREAM_DRAW = 0x000088e0; |
||||||
|
public static final int GL_SUBPIXEL_BITS = 0x00000d50; |
||||||
|
public static final int GL_TEXTURE = 0x00001702; |
||||||
|
public static final int GL_TEXTURE0 = 0x000084c0; |
||||||
|
public static final int GL_TEXTURE_2D = 0x00000de1; |
||||||
|
public static final int GL_TEXTURE_CUBE_MAP = 0x00008513; |
||||||
|
public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x00008515; |
||||||
|
public static final int GL_TEXTURE_MAG_FILTER = 0x00002800; |
||||||
|
public static final int GL_TEXTURE_MIN_FILTER = 0x00002801; |
||||||
|
public static final int GL_TEXTURE_WRAP_S = 0x00002802; |
||||||
|
public static final int GL_TEXTURE_WRAP_T = 0x00002803; |
||||||
|
public static final int GL_TRIANGLES = 0x00000004; |
||||||
|
public static final int GL_TRIANGLE_FAN = 0x00000006; |
||||||
|
public static final int GL_TRIANGLE_STRIP = 0x00000005; |
||||||
|
public static final int GL_TRUE = 0x00000001; |
||||||
|
public static final int GL_UNPACK_ALIGNMENT = 0x00000cf5; |
||||||
|
public static final int GL_UNSIGNED_BYTE = 0x00001401; |
||||||
|
public static final int GL_UNSIGNED_INT = 0x00001405; |
||||||
|
public static final int GL_UNSIGNED_SHORT = 0x00001403; |
||||||
|
public static final int GL_UNSIGNED_SHORT_4_4_4_4 = 0x00008033; |
||||||
|
public static final int GL_UNSIGNED_SHORT_5_5_5_1 = 0x00008034; |
||||||
|
public static final int GL_UNSIGNED_SHORT_5_6_5 = 0x00008363; |
||||||
|
public static final int GL_VENDOR = 0x00001f00; |
||||||
|
public static final int GL_VERSION = 0x00001f02; |
||||||
|
public static final int GL_VERTEX_SHADER = 0x00008b31; |
||||||
|
public static final int GL_ZERO = 0x00000000; |
||||||
|
|
||||||
|
public static native void glActiveTexture(int texture); |
||||||
|
public static native void glAttachShader(int program, int shader); |
||||||
|
public static native void glBindBuffer(int target, int buffer); |
||||||
|
public static native void glBindFramebuffer(int target, int framebuffer); |
||||||
|
public static native void glBindRenderbuffer(int target, int renderbuffer); |
||||||
|
public static native void glBindTexture(int target, int texture); |
||||||
|
// public static native void glBindVertexArray // TODO: Investigate this
|
||||||
|
public static native void glBlendFunc(int sfactor, int dfactor); |
||||||
|
public static native void glBufferData(int target, int size, Buffer data, int usage); |
||||||
|
public static native void glBufferData2(int target, int size, byte[] data, int offset, int usage); |
||||||
|
public static native void glBufferSubData(int target, int offset, int size, Buffer data); |
||||||
|
public static native void glBufferSubData2(int target, int offset, int size, byte[] data, int dataoffset); |
||||||
|
public static native int glCheckFramebufferStatus(int target); |
||||||
|
public static native void glClear(int mask); |
||||||
|
public static native void glClearColor(float red, float green, float blue, float alpha); |
||||||
|
public static native void glColorMask(boolean red, boolean green, boolean blue, boolean alpha); |
||||||
|
public static native void glCompileShader(int shader); |
||||||
|
public static native void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, int imageSize, Buffer pixels); |
||||||
|
public static native void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int imageSize, Buffer pixels); |
||||||
|
public static native int glCreateProgram(); |
||||||
|
public static native int glCreateShader(int type); |
||||||
|
public static native void glCullFace(int mode); |
||||||
|
public static native void glDeleteBuffers(int n, int[] buffers, int offset); |
||||||
|
public static native void glDeleteFramebuffers(int n, int[] framebuffers, int offset); |
||||||
|
public static native void glDeleteProgram(int program); |
||||||
|
public static native void glDeleteRenderbuffers(int n, int[] renderbuffers, int offset); |
||||||
|
public static native void glDeleteShader(int shader); |
||||||
|
public static native void glDeleteTextures(int n, int[] textures, int offset); |
||||||
|
public static native void glDepthFunc(int func); |
||||||
|
public static native void glDepthMask(boolean flag); |
||||||
|
public static native void glDepthRangef(float zNear, float zFar); |
||||||
|
public static native void glDetachShader(int program, int shader); |
||||||
|
public static native void glDisableVertexAttribArray(int index); |
||||||
|
public static native void glDisable(int cap); |
||||||
|
public static native void glDrawArrays(int mode, int first, int count); |
||||||
|
public static native void glDrawElements(int mode, int count, int type, Buffer indices); |
||||||
|
public static native void glDrawElements2(int mode, int count, int type, byte[] indices, int offset); |
||||||
|
public static native void glDrawElementsIndex(int mode, int count, int type, int offset); |
||||||
|
public static native void glEnable(int cap); |
||||||
|
public static native void glEnableVertexAttribArray(int index); |
||||||
|
public static native void glFramebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer); |
||||||
|
public static native void glFramebufferTexture2D(int target, int attachment, int textarget, int texture, int level); |
||||||
|
public static native void glGenBuffers(int n, int[] buffers, int offset); |
||||||
|
public static native void glGenFramebuffers(int n, int[] framebuffers, int offset); |
||||||
|
public static native void glGenRenderbuffers(int n, int[] renderbuffers, int offset); |
||||||
|
public static native void glGenTextures(int n, int[] textures, int offset); |
||||||
|
public static native void glGenerateMipmap(int target); |
||||||
|
public static native int glGetAttribLocation(int program, String name); |
||||||
|
public static native int glGetError(); |
||||||
|
public static native void glGetFramebufferAttachmentParameteriv(int target, int attachment, int pname, int[] params, int offset); |
||||||
|
public static native void glGetIntegerv (int pname, int[] params, int offset); |
||||||
|
public static native String glGetProgramInfoLog(int program); |
||||||
|
public static native void glGetProgramiv(int program, int pname, int[] params, int offset); |
||||||
|
public static native String glGetShaderInfoLog(int shader); |
||||||
|
public static native void glGetShaderiv(int shader, int pname, int[] params, int offset); |
||||||
|
public static native String glGetString(int name); |
||||||
|
public static native int glGetUniformLocation(int program, String name); |
||||||
|
public static native boolean glIsFramebuffer(int framebuffer); |
||||||
|
public static native boolean glIsRenderbuffer(int renderbuffer); |
||||||
|
public static native void glLineWidth(float width); |
||||||
|
public static native void glLinkProgram(int program); |
||||||
|
public static native void glPixelStorei(int pname, int param); |
||||||
|
public static native void glPolygonOffset(float factor, float units); |
||||||
|
public static native void glReadPixels(int vpX, int vpY, int vpW, int vpH, int format, int type, Buffer pixels); |
||||||
|
public static native void glReadPixels2(int vpX, int vpY, int vpW, int vpH, int format, int type, byte[] pixels, int offset, int size); |
||||||
|
public static native void glRenderbufferStorage(int target, int internalformat, int width, int height); |
||||||
|
public static native void glScissor(int x, int y, int width, int height); |
||||||
|
public static native void glShaderSource(int shader, String string); |
||||||
|
public static native void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, Buffer pixels); |
||||||
|
public static native void glTexParameteri(int target, int pname, int param); |
||||||
|
public static native void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, Buffer pixels); |
||||||
|
public static native void glUniform1f(int location, float x); |
||||||
|
public static native void glUniform1fv(int location, int count, FloatBuffer v); |
||||||
|
public static native void glUniform1fv2(int location, int count, float[] v, int offset); |
||||||
|
public static native void glUniform1i(int location, int x); |
||||||
|
public static native void glUniform1iv(int location, int count, IntBuffer v); |
||||||
|
public static native void glUniform1iv2(int location, int count, int[] v, int offset); |
||||||
|
public static native void glUniform2f(int location, float x, float y); |
||||||
|
public static native void glUniform2fv(int location, int count, FloatBuffer v); |
||||||
|
public static native void glUniform2fv2(int location, int count, float[] v, int offset); |
||||||
|
public static native void glUniform3f(int location, float x, float y, float z); |
||||||
|
public static native void glUniform3fv(int location, int count, FloatBuffer v); |
||||||
|
public static native void glUniform3fv2(int location, int count, float[] v, int offset); |
||||||
|
public static native void glUniform4f(int location, float x, float y, float z, float w); |
||||||
|
public static native void glUniform4fv(int location, int count, FloatBuffer v); |
||||||
|
public static native void glUniform4fv2(int location, int count, float[] v, int offset); |
||||||
|
public static native void glUniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer value); |
||||||
|
public static native void glUniformMatrix3fv2(int location, int count, boolean transpose, float[] value, int offset); |
||||||
|
public static native void glUniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer value); |
||||||
|
public static native void glUniformMatrix4fv2(int location, int count, boolean transpose, float[] value, int offset); |
||||||
|
public static native void glUseProgram(int program); |
||||||
|
//public static native void glVertexAttribPointer(int indx, int size, int type, boolean normalized, int stride, byte[] ptr, int offset);
|
||||||
|
public static native void glVertexAttribPointer(int indx, int size, int type, boolean normalized, int stride, Buffer ptr); |
||||||
|
public static native void glVertexAttribPointer2(int indx, int size, int type, boolean normalized, int stride, int offset); |
||||||
|
public static native void glViewport(int x, int y, int width, int height); |
||||||
|
|
||||||
|
|
||||||
|
public static void checkGLError() { |
||||||
|
if (!ENABLE_ERROR_CHECKING) { |
||||||
|
return; |
||||||
|
} |
||||||
|
int error = glGetError(); |
||||||
|
if (error != 0) { |
||||||
|
String message = null;//GLU.gluErrorString(error);
|
||||||
|
if (message == null) { |
||||||
|
throw new RendererException("An unknown [" + error + "] OpenGL error has occurred."); |
||||||
|
} else { |
||||||
|
throw new RendererException("An OpenGL error has occurred: " + message); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
public static String gluErrorString(int error) { |
||||||
|
switch (error) { |
||||||
|
case GL10.GL_NO_ERROR: |
||||||
|
return "no error"; |
||||||
|
case GL10.GL_INVALID_ENUM: |
||||||
|
return "invalid enum"; |
||||||
|
case GL10.GL_INVALID_VALUE: |
||||||
|
return "invalid value"; |
||||||
|
case GL10.GL_INVALID_OPERATION: |
||||||
|
return "invalid operation"; |
||||||
|
case GL10.GL_STACK_OVERFLOW: |
||||||
|
return "stack overflow"; |
||||||
|
case GL10.GL_STACK_UNDERFLOW: |
||||||
|
return "stack underflow"; |
||||||
|
case GL10.GL_OUT_OF_MEMORY: |
||||||
|
return "out of memory"; |
||||||
|
default: |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
} |
@ -0,0 +1,591 @@ |
|||||||
|
package com.jme3.renderer.ios; |
||||||
|
|
||||||
|
//import android.graphics.Bitmap;
|
||||||
|
//import android.opengl.ETC1;
|
||||||
|
//import android.opengl.ETC1Util.ETC1Texture;
|
||||||
|
//import android.opengl.JmeIosGLES;
|
||||||
|
//import android.opengl.GLUtils;
|
||||||
|
//import com.jme3.asset.AndroidImageInfo;
|
||||||
|
import com.jme3.renderer.ios.JmeIosGLES; |
||||||
|
import com.jme3.math.FastMath; |
||||||
|
import com.jme3.renderer.RendererException; |
||||||
|
import com.jme3.texture.Image; |
||||||
|
import com.jme3.texture.Image.Format; |
||||||
|
import com.jme3.util.BufferUtils; |
||||||
|
import java.nio.ByteBuffer; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
public class TextureUtil { |
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(TextureUtil.class.getName()); |
||||||
|
//TODO Make this configurable through appSettings
|
||||||
|
public static boolean ENABLE_COMPRESSION = true; |
||||||
|
private static boolean NPOT = false; |
||||||
|
private static boolean ETC1support = false; |
||||||
|
private static boolean DXT1 = false; |
||||||
|
private static boolean PVRTC = false; |
||||||
|
private static boolean DEPTH24_STENCIL8 = false; |
||||||
|
private static boolean DEPTH_TEXTURE = false; |
||||||
|
private static boolean RGBA8 = false; |
||||||
|
|
||||||
|
// Same constant used by both GL_ARM_rgba8 and GL_OES_rgb8_rgba8.
|
||||||
|
private static final int GL_RGBA8 = 0x8058; |
||||||
|
|
||||||
|
private static final int GL_DXT1 = 0x83F0; |
||||||
|
private static final int GL_DXT1A = 0x83F1; |
||||||
|
|
||||||
|
private static final int GL_DEPTH_STENCIL_OES = 0x84F9; |
||||||
|
private static final int GL_UNSIGNED_INT_24_8_OES = 0x84FA; |
||||||
|
private static final int GL_DEPTH24_STENCIL8_OES = 0x88F0; |
||||||
|
|
||||||
|
public static void loadTextureFeatures(String extensionString) { |
||||||
|
ETC1support = extensionString.contains("GL_OES_compressed_ETC1_RGB8_texture"); |
||||||
|
DEPTH24_STENCIL8 = extensionString.contains("GL_OES_packed_depth_stencil"); |
||||||
|
NPOT = extensionString.contains("GL_IMG_texture_npot") |
||||||
|
|| extensionString.contains("GL_OES_texture_npot") |
||||||
|
|| extensionString.contains("GL_NV_texture_npot_2D_mipmap"); |
||||||
|
|
||||||
|
PVRTC = extensionString.contains("GL_IMG_texture_compression_pvrtc"); |
||||||
|
|
||||||
|
DXT1 = extensionString.contains("GL_EXT_texture_compression_dxt1"); |
||||||
|
DEPTH_TEXTURE = extensionString.contains("GL_OES_depth_texture"); |
||||||
|
|
||||||
|
RGBA8 = extensionString.contains("GL_ARM_rgba8") || |
||||||
|
extensionString.contains("GL_OES_rgb8_rgba8"); |
||||||
|
|
||||||
|
logger.log(Level.FINE, "Supports ETC1? {0}", ETC1support); |
||||||
|
logger.log(Level.FINE, "Supports DEPTH24_STENCIL8? {0}", DEPTH24_STENCIL8); |
||||||
|
logger.log(Level.FINE, "Supports NPOT? {0}", NPOT); |
||||||
|
logger.log(Level.FINE, "Supports PVRTC? {0}", PVRTC); |
||||||
|
logger.log(Level.FINE, "Supports DXT1? {0}", DXT1); |
||||||
|
logger.log(Level.FINE, "Supports DEPTH_TEXTURE? {0}", DEPTH_TEXTURE); |
||||||
|
logger.log(Level.FINE, "Supports RGBA8? {0}", RGBA8); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
private static void buildMipmap(Bitmap bitmap, boolean compress) { |
||||||
|
int level = 0; |
||||||
|
int height = bitmap.getHeight(); |
||||||
|
int width = bitmap.getWidth(); |
||||||
|
|
||||||
|
logger.log(Level.FINEST, " - Generating mipmaps for bitmap using SOFTWARE"); |
||||||
|
|
||||||
|
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1); |
||||||
|
|
||||||
|
while (height >= 1 || width >= 1) { |
||||||
|
//First of all, generate the texture from our bitmap and set it to the according level
|
||||||
|
if (compress) { |
||||||
|
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) with compression.", new Object[]{level, width, height}); |
||||||
|
uploadBitmapAsCompressed(JmeIosGLES.GL_TEXTURE_2D, level, bitmap, false, 0, 0); |
||||||
|
} else { |
||||||
|
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) directly.", new Object[]{level, width, height}); |
||||||
|
GLUtils.texImage2D(JmeIosGLES.GL_TEXTURE_2D, level, bitmap, 0); |
||||||
|
} |
||||||
|
|
||||||
|
if (height == 1 || width == 1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
//Increase the mipmap level
|
||||||
|
height /= 2; |
||||||
|
width /= 2; |
||||||
|
Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); |
||||||
|
|
||||||
|
// Recycle any bitmaps created as a result of scaling the bitmap.
|
||||||
|
// Do not recycle the original image (mipmap level 0)
|
||||||
|
if (level != 0) { |
||||||
|
bitmap.recycle(); |
||||||
|
} |
||||||
|
|
||||||
|
bitmap = bitmap2; |
||||||
|
|
||||||
|
level++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void uploadBitmapAsCompressed(int target, int level, Bitmap bitmap, boolean subTexture, int x, int y) { |
||||||
|
if (bitmap.hasAlpha()) { |
||||||
|
logger.log(Level.FINEST, " - Uploading bitmap directly. Cannot compress as alpha present."); |
||||||
|
if (subTexture) { |
||||||
|
GLUtils.texSubImage2D(target, level, x, y, bitmap); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} else { |
||||||
|
GLUtils.texImage2D(target, level, bitmap, 0); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
// Convert to RGB565
|
||||||
|
int bytesPerPixel = 2; |
||||||
|
Bitmap rgb565 = bitmap.copy(Bitmap.Config.RGB_565, true); |
||||||
|
|
||||||
|
// Put texture data into ByteBuffer
|
||||||
|
ByteBuffer inputImage = BufferUtils.createByteBuffer(bitmap.getRowBytes() * bitmap.getHeight()); |
||||||
|
rgb565.copyPixelsToBuffer(inputImage); |
||||||
|
inputImage.position(0); |
||||||
|
|
||||||
|
// Delete the copied RGB565 image
|
||||||
|
rgb565.recycle(); |
||||||
|
|
||||||
|
// Encode the image into the output bytebuffer
|
||||||
|
int encodedImageSize = ETC1.getEncodedDataSize(bitmap.getWidth(), bitmap.getHeight()); |
||||||
|
ByteBuffer compressedImage = BufferUtils.createByteBuffer(encodedImageSize); |
||||||
|
ETC1.encodeImage(inputImage, bitmap.getWidth(), |
||||||
|
bitmap.getHeight(), |
||||||
|
bytesPerPixel, |
||||||
|
bytesPerPixel * bitmap.getWidth(), |
||||||
|
compressedImage); |
||||||
|
|
||||||
|
// Delete the input image buffer
|
||||||
|
BufferUtils.destroyDirectBuffer(inputImage); |
||||||
|
|
||||||
|
// Create an ETC1Texture from the compressed image data
|
||||||
|
ETC1Texture etc1tex = new ETC1Texture(bitmap.getWidth(), bitmap.getHeight(), compressedImage); |
||||||
|
|
||||||
|
// Upload the ETC1Texture
|
||||||
|
if (bytesPerPixel == 2) { |
||||||
|
int oldSize = (bitmap.getRowBytes() * bitmap.getHeight()); |
||||||
|
int newSize = compressedImage.capacity(); |
||||||
|
logger.log(Level.FINEST, " - Uploading compressed image to GL, oldSize = {0}, newSize = {1}, ratio = {2}", new Object[]{oldSize, newSize, (float) oldSize / newSize}); |
||||||
|
if (subTexture) { |
||||||
|
JmeIosGLES.glCompressedTexSubImage2D(target, |
||||||
|
level, |
||||||
|
x, y, |
||||||
|
bitmap.getWidth(), |
||||||
|
bitmap.getHeight(), |
||||||
|
ETC1.ETC1_RGB8_OES, |
||||||
|
etc1tex.getData().capacity(), |
||||||
|
etc1tex.getData()); |
||||||
|
|
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} else { |
||||||
|
JmeIosGLES.glCompressedTexImage2D(target, |
||||||
|
level, |
||||||
|
ETC1.ETC1_RGB8_OES, |
||||||
|
bitmap.getWidth(), |
||||||
|
bitmap.getHeight(), |
||||||
|
0, |
||||||
|
etc1tex.getData().capacity(), |
||||||
|
etc1tex.getData()); |
||||||
|
|
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
|
||||||
|
// ETC1Util.loadTexture(target, level, 0, JmeIosGLES.GL_RGB,
|
||||||
|
// JmeIosGLES.GL_UNSIGNED_SHORT_5_6_5, etc1Texture);
|
||||||
|
// } else if (bytesPerPixel == 3) {
|
||||||
|
// ETC1Util.loadTexture(target, level, 0, JmeIosGLES.GL_RGB,
|
||||||
|
// JmeIosGLES.GL_UNSIGNED_BYTE, etc1Texture);
|
||||||
|
} |
||||||
|
|
||||||
|
BufferUtils.destroyDirectBuffer(compressedImage); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>uploadTextureBitmap</code> uploads a native android bitmap |
||||||
|
*/ |
||||||
|
/* |
||||||
|
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips) { |
||||||
|
uploadTextureBitmap(target, bitmap, needMips, false, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <code>uploadTextureBitmap</code> uploads a native android bitmap |
||||||
|
*/ |
||||||
|
/* |
||||||
|
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips, boolean subTexture, int x, int y) { |
||||||
|
boolean recycleBitmap = false; |
||||||
|
//TODO, maybe this should raise an exception when NPOT is not supported
|
||||||
|
|
||||||
|
boolean willCompress = ENABLE_COMPRESSION && ETC1support && !bitmap.hasAlpha(); |
||||||
|
if (needMips && willCompress) { |
||||||
|
// Image is compressed and mipmaps are desired, generate them
|
||||||
|
// using software.
|
||||||
|
buildMipmap(bitmap, willCompress); |
||||||
|
} else { |
||||||
|
if (willCompress) { |
||||||
|
// Image is compressed but mipmaps are not desired, upload directly.
|
||||||
|
logger.log(Level.FINEST, " - Uploading compressed bitmap. Mipmaps are not generated."); |
||||||
|
uploadBitmapAsCompressed(target, 0, bitmap, subTexture, x, y); |
||||||
|
|
||||||
|
} else { |
||||||
|
// Image is not compressed, mipmaps may or may not be desired.
|
||||||
|
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}", |
||||||
|
(needMips |
||||||
|
? " Mipmaps will be generated in HARDWARE" |
||||||
|
: " Mipmaps are not generated.")); |
||||||
|
if (subTexture) { |
||||||
|
System.err.println("x : " + x + " y :" + y + " , " + bitmap.getWidth() + "/" + bitmap.getHeight()); |
||||||
|
GLUtils.texSubImage2D(target, 0, x, y, bitmap); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} else { |
||||||
|
GLUtils.texImage2D(target, 0, bitmap, 0); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
|
||||||
|
if (needMips) { |
||||||
|
// No pregenerated mips available,
|
||||||
|
// generate from base level if required
|
||||||
|
JmeIosGLES.glGenerateMipmap(target); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (recycleBitmap) { |
||||||
|
bitmap.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
public static void uploadTextureAny(Image img, int target, int index, boolean needMips) { |
||||||
|
/* |
||||||
|
if (img.getEfficentData() instanceof AndroidImageInfo) { |
||||||
|
logger.log(Level.FINEST, " === Uploading image {0}. Using BITMAP PATH === ", img); |
||||||
|
// If image was loaded from asset manager, use fast path
|
||||||
|
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData(); |
||||||
|
uploadTextureBitmap(target, imageInfo.getBitmap(), needMips); |
||||||
|
} else { |
||||||
|
*/ |
||||||
|
logger.log(Level.FINEST, " === Uploading image {0}. Using BUFFER PATH === ", img); |
||||||
|
boolean wantGeneratedMips = needMips && !img.hasMipmaps(); |
||||||
|
if (wantGeneratedMips && img.getFormat().isCompressed()) { |
||||||
|
logger.log(Level.WARNING, "Generating mipmaps is only" |
||||||
|
+ " supported for Bitmap based or non-compressed images!"); |
||||||
|
} |
||||||
|
|
||||||
|
// Upload using slower path
|
||||||
|
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}", |
||||||
|
(wantGeneratedMips |
||||||
|
? " Mipmaps will be generated in HARDWARE" |
||||||
|
: " Mipmaps are not generated.")); |
||||||
|
|
||||||
|
uploadTexture(img, target, index); |
||||||
|
|
||||||
|
// Image was uploaded using slower path, since it is not compressed,
|
||||||
|
// then compress it
|
||||||
|
if (wantGeneratedMips) { |
||||||
|
// No pregenerated mips available,
|
||||||
|
// generate from base level if required
|
||||||
|
JmeIosGLES.glGenerateMipmap(target); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
//}
|
||||||
|
} |
||||||
|
|
||||||
|
private static void unsupportedFormat(Format fmt) { |
||||||
|
throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware."); |
||||||
|
} |
||||||
|
|
||||||
|
public static IosGLImageFormat getImageFormat(Format fmt) throws UnsupportedOperationException { |
||||||
|
IosGLImageFormat imageFormat = new IosGLImageFormat(); |
||||||
|
switch (fmt) { |
||||||
|
case RGBA16: |
||||||
|
case RGB16: |
||||||
|
case RGB10: |
||||||
|
case Luminance16: |
||||||
|
case Luminance16Alpha16: |
||||||
|
case Alpha16: |
||||||
|
case Depth32: |
||||||
|
case Depth32F: |
||||||
|
throw new UnsupportedOperationException("The image format '" |
||||||
|
+ fmt + "' is not supported by OpenGL ES 2.0 specification."); |
||||||
|
case Alpha8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_ALPHA; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
// Highest precision alpha supported by vanilla OGLES2
|
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4; |
||||||
|
} |
||||||
|
break; |
||||||
|
case Luminance8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_LUMINANCE; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
// Highest precision luminance supported by vanilla OGLES2
|
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565; |
||||||
|
} |
||||||
|
break; |
||||||
|
case Luminance8Alpha8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_LUMINANCE_ALPHA; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4; |
||||||
|
} |
||||||
|
break; |
||||||
|
case RGB565: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGB; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_5_6_5; |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565; |
||||||
|
break; |
||||||
|
case ARGB4444: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGBA4; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_4_4_4_4; |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4; |
||||||
|
break; |
||||||
|
case RGB5A1: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGBA; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_5_5_5_1; |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB5_A1; |
||||||
|
break; |
||||||
|
case RGB8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGB; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
// Fallback: Use RGB565 if RGBA8 is not available.
|
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565; |
||||||
|
} |
||||||
|
break; |
||||||
|
case BGR8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGB; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565; |
||||||
|
} |
||||||
|
break; |
||||||
|
case RGBA8: |
||||||
|
imageFormat.format = JmeIosGLES.GL_RGBA; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
if (RGBA8) { |
||||||
|
imageFormat.renderBufferStorageFormat = GL_RGBA8; |
||||||
|
} else { |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4; |
||||||
|
} |
||||||
|
break; |
||||||
|
case Depth: |
||||||
|
case Depth16: |
||||||
|
if (!DEPTH_TEXTURE) { |
||||||
|
unsupportedFormat(fmt); |
||||||
|
} |
||||||
|
imageFormat.format = JmeIosGLES.GL_DEPTH_COMPONENT; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT; |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_DEPTH_COMPONENT16; |
||||||
|
break; |
||||||
|
case Depth24: |
||||||
|
case Depth24Stencil8: |
||||||
|
if (!DEPTH_TEXTURE) { |
||||||
|
unsupportedFormat(fmt); |
||||||
|
} |
||||||
|
if (DEPTH24_STENCIL8) { |
||||||
|
// NEW: True Depth24 + Stencil8 format.
|
||||||
|
imageFormat.format = GL_DEPTH_STENCIL_OES; |
||||||
|
imageFormat.dataType = GL_UNSIGNED_INT_24_8_OES; |
||||||
|
imageFormat.renderBufferStorageFormat = GL_DEPTH24_STENCIL8_OES; |
||||||
|
} else { |
||||||
|
// Vanilla OGLES2, only Depth16 available.
|
||||||
|
imageFormat.format = JmeIosGLES.GL_DEPTH_COMPONENT; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT; |
||||||
|
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_DEPTH_COMPONENT16; |
||||||
|
} |
||||||
|
break; |
||||||
|
case DXT1: |
||||||
|
if (!DXT1) { |
||||||
|
unsupportedFormat(fmt); |
||||||
|
} |
||||||
|
imageFormat.format = GL_DXT1; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
imageFormat.compress = true; |
||||||
|
break; |
||||||
|
case DXT1A: |
||||||
|
if (!DXT1) { |
||||||
|
unsupportedFormat(fmt); |
||||||
|
} |
||||||
|
imageFormat.format = GL_DXT1A; |
||||||
|
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE; |
||||||
|
imageFormat.compress = true; |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new UnsupportedOperationException("Unrecognized format: " + fmt); |
||||||
|
} |
||||||
|
return imageFormat; |
||||||
|
} |
||||||
|
|
||||||
|
public static class IosGLImageFormat { |
||||||
|
|
||||||
|
boolean compress = false; |
||||||
|
int format = -1; |
||||||
|
int renderBufferStorageFormat = -1; |
||||||
|
int dataType = -1; |
||||||
|
} |
||||||
|
|
||||||
|
private static void uploadTexture(Image img, |
||||||
|
int target, |
||||||
|
int index) { |
||||||
|
|
||||||
|
/* |
||||||
|
if (img.getEfficentData() instanceof AndroidImageInfo) { |
||||||
|
throw new RendererException("This image uses efficient data. " |
||||||
|
+ "Use uploadTextureBitmap instead."); |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
// Otherwise upload image directly.
|
||||||
|
// Prefer to only use power of 2 textures here to avoid errors.
|
||||||
|
Image.Format fmt = img.getFormat(); |
||||||
|
ByteBuffer data; |
||||||
|
if (index >= 0 || img.getData() != null && img.getData().size() > 0) { |
||||||
|
data = img.getData(index); |
||||||
|
} else { |
||||||
|
data = null; |
||||||
|
} |
||||||
|
|
||||||
|
int width = img.getWidth(); |
||||||
|
int height = img.getHeight(); |
||||||
|
|
||||||
|
if (!NPOT) { |
||||||
|
// Check if texture is POT
|
||||||
|
if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) { |
||||||
|
throw new RendererException("Non-power-of-2 textures " |
||||||
|
+ "are not supported by the video hardware " |
||||||
|
+ "and no scaling path available for image: " + img); |
||||||
|
} |
||||||
|
} |
||||||
|
IosGLImageFormat imageFormat = getImageFormat(fmt); |
||||||
|
|
||||||
|
if (data != null) { |
||||||
|
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
|
||||||
|
int[] mipSizes = img.getMipMapSizes(); |
||||||
|
int pos = 0; |
||||||
|
if (mipSizes == null) { |
||||||
|
if (data != null) { |
||||||
|
mipSizes = new int[]{data.capacity()}; |
||||||
|
} else { |
||||||
|
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < mipSizes.length; i++) { |
||||||
|
int mipWidth = Math.max(1, width >> i); |
||||||
|
int mipHeight = Math.max(1, height >> i); |
||||||
|
|
||||||
|
if (data != null) { |
||||||
|
data.position(pos); |
||||||
|
data.limit(pos + mipSizes[i]); |
||||||
|
} |
||||||
|
|
||||||
|
if (imageFormat.compress && data != null) { |
||||||
|
JmeIosGLES.glCompressedTexImage2D(target, |
||||||
|
i, |
||||||
|
imageFormat.format, |
||||||
|
mipWidth, |
||||||
|
mipHeight, |
||||||
|
0, |
||||||
|
data.remaining(), |
||||||
|
data); |
||||||
|
} else { |
||||||
|
JmeIosGLES.glTexImage2D(target, |
||||||
|
i, |
||||||
|
imageFormat.format, |
||||||
|
mipWidth, |
||||||
|
mipHeight, |
||||||
|
0, |
||||||
|
imageFormat.format, |
||||||
|
imageFormat.dataType, |
||||||
|
data); |
||||||
|
} |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
|
||||||
|
pos += mipSizes[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Update the texture currently bound to target at with data from the given |
||||||
|
* Image at position x and y. The parameter index is used as the zoffset in |
||||||
|
* case a 3d texture or texture 2d array is being updated. |
||||||
|
* |
||||||
|
* @param image Image with the source data (this data will be put into the |
||||||
|
* texture) |
||||||
|
* @param target the target texture |
||||||
|
* @param index the mipmap level to update |
||||||
|
* @param x the x position where to put the image in the texture |
||||||
|
* @param y the y position where to put the image in the texture |
||||||
|
*/ |
||||||
|
public static void uploadSubTexture( |
||||||
|
Image img, |
||||||
|
int target, |
||||||
|
int index, |
||||||
|
int x, |
||||||
|
int y) { |
||||||
|
//TODO:
|
||||||
|
/* |
||||||
|
if (img.getEfficentData() instanceof AndroidImageInfo) { |
||||||
|
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData(); |
||||||
|
uploadTextureBitmap(target, imageInfo.getBitmap(), true, true, x, y); |
||||||
|
return; |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
// Otherwise upload image directly.
|
||||||
|
// Prefer to only use power of 2 textures here to avoid errors.
|
||||||
|
Image.Format fmt = img.getFormat(); |
||||||
|
ByteBuffer data; |
||||||
|
if (index >= 0 || img.getData() != null && img.getData().size() > 0) { |
||||||
|
data = img.getData(index); |
||||||
|
} else { |
||||||
|
data = null; |
||||||
|
} |
||||||
|
|
||||||
|
int width = img.getWidth(); |
||||||
|
int height = img.getHeight(); |
||||||
|
|
||||||
|
if (!NPOT) { |
||||||
|
// Check if texture is POT
|
||||||
|
if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) { |
||||||
|
throw new RendererException("Non-power-of-2 textures " |
||||||
|
+ "are not supported by the video hardware " |
||||||
|
+ "and no scaling path available for image: " + img); |
||||||
|
} |
||||||
|
} |
||||||
|
IosGLImageFormat imageFormat = getImageFormat(fmt); |
||||||
|
|
||||||
|
if (data != null) { |
||||||
|
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
|
||||||
|
int[] mipSizes = img.getMipMapSizes(); |
||||||
|
int pos = 0; |
||||||
|
if (mipSizes == null) { |
||||||
|
if (data != null) { |
||||||
|
mipSizes = new int[]{data.capacity()}; |
||||||
|
} else { |
||||||
|
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < mipSizes.length; i++) { |
||||||
|
int mipWidth = Math.max(1, width >> i); |
||||||
|
int mipHeight = Math.max(1, height >> i); |
||||||
|
|
||||||
|
if (data != null) { |
||||||
|
data.position(pos); |
||||||
|
data.limit(pos + mipSizes[i]); |
||||||
|
} |
||||||
|
|
||||||
|
if (imageFormat.compress && data != null) { |
||||||
|
JmeIosGLES.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, data.remaining(), data); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} else { |
||||||
|
JmeIosGLES.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, imageFormat.dataType, data); |
||||||
|
JmeIosGLES.checkGLError(); |
||||||
|
} |
||||||
|
|
||||||
|
pos += mipSizes[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,201 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.system.ios; |
||||||
|
|
||||||
|
import com.jme3.input.*; |
||||||
|
import com.jme3.input.controls.SoftTextDialogInputListener; |
||||||
|
import com.jme3.input.dummy.DummyKeyInput; |
||||||
|
import com.jme3.input.dummy.DummyMouseInput; |
||||||
|
import com.jme3.renderer.ios.IGLESShaderRenderer; |
||||||
|
import com.jme3.system.*; |
||||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
public class IGLESContext implements JmeContext { |
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(IGLESContext.class.getName()); |
||||||
|
protected final AtomicBoolean created = new AtomicBoolean(false); |
||||||
|
protected final AtomicBoolean renderable = new AtomicBoolean(false); |
||||||
|
protected final AtomicBoolean needClose = new AtomicBoolean(false); |
||||||
|
protected AppSettings settings = new AppSettings(true); |
||||||
|
protected boolean autoFlush = true; |
||||||
|
|
||||||
|
/* |
||||||
|
* >= OpenGL ES 2.0 (iOS) |
||||||
|
*/ |
||||||
|
protected IGLESShaderRenderer renderer; |
||||||
|
protected Timer timer; |
||||||
|
protected SystemListener listener; |
||||||
|
protected int minFrameDuration = 0; // No FPS cap
|
||||||
|
|
||||||
|
public IGLESContext() { |
||||||
|
logger.log(Level.FINE, "IGLESContext constructor"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Type getType() { |
||||||
|
return Type.Display; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSettings(AppSettings settings) { |
||||||
|
logger.log(Level.FINE, "IGLESContext setSettings"); |
||||||
|
this.settings.copyFrom(settings); |
||||||
|
/* |
||||||
|
if (androidInput != null) { |
||||||
|
androidInput.loadSettings(settings); |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSystemListener(SystemListener listener) { |
||||||
|
logger.log(Level.FINE, "IGLESContext setSystemListener"); |
||||||
|
this.listener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AppSettings getSettings() { |
||||||
|
return settings; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public com.jme3.renderer.Renderer getRenderer() { |
||||||
|
logger.log(Level.FINE, "IGLESContext getRenderer"); |
||||||
|
return renderer; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public MouseInput getMouseInput() { |
||||||
|
return new DummyMouseInput(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyInput getKeyInput() { |
||||||
|
return new DummyKeyInput(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JoyInput getJoyInput() { |
||||||
|
/* |
||||||
|
if (androidSensorJoyInput == null) { |
||||||
|
androidSensorJoyInput = new AndroidSensorJoyInput(); |
||||||
|
} |
||||||
|
return androidSensorJoyInput; |
||||||
|
*/ |
||||||
|
return null;// new DummySensorJoyInput();
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TouchInput getTouchInput() { |
||||||
|
//return androidInput;
|
||||||
|
return null;// new DummyTouchInput();
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Timer getTimer() { |
||||||
|
return timer; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setTitle(String title) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCreated() { |
||||||
|
logger.log(Level.FINE, "IGLESContext isCreated"); |
||||||
|
return created.get(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAutoFlushFrames(boolean enabled) { |
||||||
|
this.autoFlush = enabled; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isRenderable() { |
||||||
|
logger.log(Level.FINE, "IGLESContext isRenderable"); |
||||||
|
return true;// renderable.get();
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void create(boolean waitFor) { |
||||||
|
logger.log(Level.FINE, "IGLESContext create"); |
||||||
|
renderer = new IGLESShaderRenderer(); |
||||||
|
timer = new NanoTimer(); |
||||||
|
|
||||||
|
//synchronized (createdLock){
|
||||||
|
created.set(true); |
||||||
|
//createdLock.notifyAll();
|
||||||
|
//}
|
||||||
|
|
||||||
|
listener.initialize(); |
||||||
|
|
||||||
|
if (waitFor) { |
||||||
|
//waitFor(true);
|
||||||
|
} |
||||||
|
logger.log(Level.FINE, "IGLESContext created"); |
||||||
|
} |
||||||
|
|
||||||
|
public void create() { |
||||||
|
create(false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void restart() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy(boolean waitFor) { |
||||||
|
logger.log(Level.FINE, "IGLESContext destroy"); |
||||||
|
listener.destroy(); |
||||||
|
needClose.set(true); |
||||||
|
if (waitFor) { |
||||||
|
//waitFor(false);
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void destroy() { |
||||||
|
destroy(true); |
||||||
|
} |
||||||
|
|
||||||
|
protected void waitFor(boolean createdVal) { |
||||||
|
while (renderable.get() != createdVal) { |
||||||
|
try { |
||||||
|
Thread.sleep(10); |
||||||
|
} catch (InterruptedException ex) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.blender.filetypes; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import org.openide.awt.ActionID; |
||||||
|
import org.openide.awt.ActionReference; |
||||||
|
import org.openide.awt.ActionReferences; |
||||||
|
import org.openide.filesystems.FileObject; |
||||||
|
import org.openide.filesystems.MIMEResolver; |
||||||
|
import org.openide.loaders.DataObject; |
||||||
|
import org.openide.loaders.DataObjectExistsException; |
||||||
|
import org.openide.loaders.MultiFileLoader; |
||||||
|
import org.openide.util.NbBundle.Messages; |
||||||
|
|
||||||
|
@Messages({ |
||||||
|
"LBL_BlenderFbx_LOADER=Files of BlenderFbx" |
||||||
|
}) |
||||||
|
@MIMEResolver.ExtensionRegistration( |
||||||
|
displayName = "#LBL_BlenderFbx_LOADER", |
||||||
|
mimeType = "application/fbx", |
||||||
|
extension = {"fbx"}) |
||||||
|
@DataObject.Registration( |
||||||
|
mimeType = "application/fbx", |
||||||
|
iconBase = "com/jme3/gde/blender/blender.png", |
||||||
|
displayName = "#LBL_BlenderFbx_LOADER", |
||||||
|
position = 300) |
||||||
|
@ActionReferences({ |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.OpenAction"), |
||||||
|
position = 100, |
||||||
|
separatorAfter = 200), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "Edit", id = "org.openide.actions.CutAction"), |
||||||
|
position = 300), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), |
||||||
|
position = 400, |
||||||
|
separatorAfter = 500), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), |
||||||
|
position = 600), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.RenameAction"), |
||||||
|
position = 700, |
||||||
|
separatorAfter = 800), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"), |
||||||
|
position = 900, |
||||||
|
separatorAfter = 1000), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), |
||||||
|
position = 1100, |
||||||
|
separatorAfter = 1200), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.ToolsAction"), |
||||||
|
position = 1300), |
||||||
|
@ActionReference( |
||||||
|
path = "Loaders/application/fbx/Actions", |
||||||
|
id = |
||||||
|
@ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), |
||||||
|
position = 1400) |
||||||
|
}) |
||||||
|
public class BlenderFbxDataObject extends AbstractBlenderImportDataObject { |
||||||
|
|
||||||
|
public BlenderFbxDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { |
||||||
|
super(pf, loader); |
||||||
|
SUFFIX = "3ds"; |
||||||
|
// registerEditor("application/fbx", false);
|
||||||
|
} |
||||||
|
// @Override
|
||||||
|
// protected int associateLookup() {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
# This script invokes blender to import and save external model formats as |
||||||
|
# .blend files to be processed further. |
||||||
|
# |
||||||
|
# Example usage for this importer: |
||||||
|
# blender --background --factory-startup --python $HOME/import_3ds.py -- \ |
||||||
|
# --i="/tmp/hello.3ds" \ |
||||||
|
# --o="/tmp/hello.blend" \ |
||||||
|
# |
||||||
|
# See blender --help for details. |
||||||
|
|
||||||
|
import bpy |
||||||
|
|
||||||
|
# Imports a file using importer |
||||||
|
def import_file(file_path): |
||||||
|
# Import the model |
||||||
|
bpy.ops.import_scene.fbx(filepath = file_path) |
||||||
|
|
||||||
|
# Clear existing objects. |
||||||
|
def clear_scene(): |
||||||
|
scene = bpy.context.scene |
||||||
|
scene.camera = None |
||||||
|
for obj in scene.objects: |
||||||
|
scene.objects.unlink(obj) |
||||||
|
|
||||||
|
# Save current scene as .blend file |
||||||
|
def save_file(save_path): |
||||||
|
# Check if output file exists already |
||||||
|
try: |
||||||
|
f = open(save_path, 'w') |
||||||
|
f.close() |
||||||
|
ok = True |
||||||
|
except: |
||||||
|
print("Cannot save to path %r" % save_path) |
||||||
|
|
||||||
|
import traceback |
||||||
|
traceback.print_exc() |
||||||
|
|
||||||
|
# Save .blend file |
||||||
|
if ok: |
||||||
|
bpy.ops.wm.save_as_mainfile(filepath=save_path) |
||||||
|
|
||||||
|
def main(): |
||||||
|
import sys # to get command line args |
||||||
|
import argparse # to parse options for us and print a nice help message |
||||||
|
|
||||||
|
# get the args passed to blender after "--", all of which are ignored by |
||||||
|
# blender so scripts may receive their own arguments |
||||||
|
argv = sys.argv |
||||||
|
|
||||||
|
if "--" not in argv: |
||||||
|
argv = [] # as if no args are passed |
||||||
|
else: |
||||||
|
argv = argv[argv.index("--") + 1:] # get all args after "--" |
||||||
|
|
||||||
|
# When --help or no args are given, print this help |
||||||
|
usage_text = \ |
||||||
|
"Run blender in background mode with this script:" |
||||||
|
" blender --background --factory-startup --python " + __file__ + " -- [options]" |
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=usage_text) |
||||||
|
|
||||||
|
# Possible types are: string, int, long, choice, float and complex. |
||||||
|
parser.add_argument("-i", "--input", dest="file_path", metavar='FILE', |
||||||
|
help="Import the specified file") |
||||||
|
parser.add_argument("-o", "--output", dest="save_path", metavar='FILE', |
||||||
|
help="Save the generated file to the specified path") |
||||||
|
|
||||||
|
args = parser.parse_args(argv) # In this example we wont use the args |
||||||
|
|
||||||
|
if not argv: |
||||||
|
parser.print_help() |
||||||
|
return |
||||||
|
|
||||||
|
# Run the conversion |
||||||
|
clear_scene() |
||||||
|
import_file(args.file_path) |
||||||
|
save_file(args.save_path) |
||||||
|
|
||||||
|
print("batch job finished, exiting") |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
Loading…
Reference in new issue