Added iOS java rendering classes
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@11034 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
be38e480b7
commit
5afe5b35c1
2571
engine/src/ios/com/jme3/renderer/ios/IGLESShaderRenderer.java
Normal file
2571
engine/src/ios/com/jme3/renderer/ios/IGLESShaderRenderer.java
Normal file
File diff suppressed because it is too large
Load Diff
273
engine/src/ios/com/jme3/renderer/ios/JmeIosGLES.java
Normal file
273
engine/src/ios/com/jme3/renderer/ios/JmeIosGLES.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
591
engine/src/ios/com/jme3/renderer/ios/TextureUtil.java
Normal file
591
engine/src/ios/com/jme3/renderer/ios/TextureUtil.java
Normal file
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user