1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.opengl; 18 19import android.graphics.Bitmap; 20 21import javax.microedition.khronos.egl.EGL10; 22import javax.microedition.khronos.egl.EGL11; 23 24/** 25 * 26 * Utility class to help bridging OpenGL ES and Android APIs. 27 * 28 */ 29 30public final class GLUtils { 31 32 /* 33 * We use a class initializer to allow the native code to cache some 34 * field offsets. 35 */ 36 static { 37 nativeClassInit(); 38 } 39 40 private GLUtils() { 41 } 42 43 /** 44 * return the internal format as defined by OpenGL ES of the supplied bitmap. 45 * @param bitmap 46 * @return the internal format of the bitmap. 47 */ 48 public static int getInternalFormat(Bitmap bitmap) { 49 if (bitmap == null) { 50 throw new NullPointerException("getInternalFormat can't be used with a null Bitmap"); 51 } 52 if (bitmap.isRecycled()) { 53 throw new IllegalArgumentException("bitmap is recycled"); 54 } 55 int result = native_getInternalFormat(bitmap); 56 if (result < 0) { 57 throw new IllegalArgumentException("Unknown internalformat"); 58 } 59 return result; 60 } 61 62 /** 63 * Return the type as defined by OpenGL ES of the supplied bitmap, if there 64 * is one. If the bitmap is stored in a compressed format, it may not have 65 * a valid OpenGL ES type. 66 * @throws IllegalArgumentException if the bitmap does not have a type. 67 * @param bitmap 68 * @return the OpenGL ES type of the bitmap. 69 */ 70 public static int getType(Bitmap bitmap) { 71 if (bitmap == null) { 72 throw new NullPointerException("getType can't be used with a null Bitmap"); 73 } 74 if (bitmap.isRecycled()) { 75 throw new IllegalArgumentException("bitmap is recycled"); 76 } 77 int result = native_getType(bitmap); 78 if (result < 0) { 79 throw new IllegalArgumentException("Unknown type"); 80 } 81 return result; 82 } 83 84 /** 85 * Calls glTexImage2D() on the current OpenGL context. If no context is 86 * current the behavior is the same as calling glTexImage2D() with no 87 * current context, that is, eglGetError() will return the appropriate 88 * error. 89 * Unlike glTexImage2D() bitmap cannot be null and will raise an exception 90 * in that case. 91 * All other parameters are identical to those used for glTexImage2D(). 92 * 93 * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make 94 * sure to set it properly according to the supplied bitmap. 95 * 96 * Whether or not bitmap can have non power of two dimensions depends on 97 * the current OpenGL context. Always check glGetError() some time 98 * after calling this method, just like when using OpenGL directly. 99 * 100 * @param target 101 * @param level 102 * @param internalformat 103 * @param bitmap 104 * @param border 105 */ 106 public static void texImage2D(int target, int level, int internalformat, 107 Bitmap bitmap, int border) { 108 if (bitmap == null) { 109 throw new NullPointerException("texImage2D can't be used with a null Bitmap"); 110 } 111 if (bitmap.isRecycled()) { 112 throw new IllegalArgumentException("bitmap is recycled"); 113 } 114 if (native_texImage2D(target, level, internalformat, bitmap, -1, border)!=0) { 115 throw new IllegalArgumentException("invalid Bitmap format"); 116 } 117 } 118 119 /** 120 * A version of texImage2D() that takes an explicit type parameter 121 * as defined by the OpenGL ES specification. The actual type and 122 * internalformat of the bitmap must be compatible with the specified 123 * type and internalformat parameters. 124 * 125 * @param target 126 * @param level 127 * @param internalformat 128 * @param bitmap 129 * @param type 130 * @param border 131 */ 132 public static void texImage2D(int target, int level, int internalformat, 133 Bitmap bitmap, int type, int border) { 134 if (bitmap == null) { 135 throw new NullPointerException("texImage2D can't be used with a null Bitmap"); 136 } 137 if (bitmap.isRecycled()) { 138 throw new IllegalArgumentException("bitmap is recycled"); 139 } 140 if (native_texImage2D(target, level, internalformat, bitmap, type, border)!=0) { 141 throw new IllegalArgumentException("invalid Bitmap format"); 142 } 143 } 144 145 /** 146 * A version of texImage2D that determines the internalFormat and type 147 * automatically. 148 * 149 * @param target 150 * @param level 151 * @param bitmap 152 * @param border 153 */ 154 public static void texImage2D(int target, int level, Bitmap bitmap, 155 int border) { 156 if (bitmap == null) { 157 throw new NullPointerException("texImage2D can't be used with a null Bitmap"); 158 } 159 if (bitmap.isRecycled()) { 160 throw new IllegalArgumentException("bitmap is recycled"); 161 } 162 if (native_texImage2D(target, level, -1, bitmap, -1, border)!=0) { 163 throw new IllegalArgumentException("invalid Bitmap format"); 164 } 165 } 166 167 /** 168 * Calls glTexSubImage2D() on the current OpenGL context. If no context is 169 * current the behavior is the same as calling glTexSubImage2D() with no 170 * current context, that is, eglGetError() will return the appropriate 171 * error. 172 * Unlike glTexSubImage2D() bitmap cannot be null and will raise an exception 173 * in that case. 174 * All other parameters are identical to those used for glTexSubImage2D(). 175 * 176 * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make 177 * sure to set it properly according to the supplied bitmap. 178 * 179 * Whether or not bitmap can have non power of two dimensions depends on 180 * the current OpenGL context. Always check glGetError() some time 181 * after calling this method, just like when using OpenGL directly. 182 * 183 * @param target 184 * @param level 185 * @param xoffset 186 * @param yoffset 187 * @param bitmap 188 */ 189 public static void texSubImage2D(int target, int level, int xoffset, int yoffset, 190 Bitmap bitmap) { 191 if (bitmap == null) { 192 throw new NullPointerException("texSubImage2D can't be used with a null Bitmap"); 193 } 194 if (bitmap.isRecycled()) { 195 throw new IllegalArgumentException("bitmap is recycled"); 196 } 197 int type = getType(bitmap); 198 if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, -1, type)!=0) { 199 throw new IllegalArgumentException("invalid Bitmap format"); 200 } 201 } 202 203 /** 204 * A version of texSubImage2D() that takes an explicit type parameter 205 * as defined by the OpenGL ES specification. 206 * 207 * @param target 208 * @param level 209 * @param xoffset 210 * @param yoffset 211 * @param bitmap 212 * @param type 213 */ 214 public static void texSubImage2D(int target, int level, int xoffset, int yoffset, 215 Bitmap bitmap, int format, int type) { 216 if (bitmap == null) { 217 throw new NullPointerException("texSubImage2D can't be used with a null Bitmap"); 218 } 219 if (bitmap.isRecycled()) { 220 throw new IllegalArgumentException("bitmap is recycled"); 221 } 222 if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, format, type)!=0) { 223 throw new IllegalArgumentException("invalid Bitmap format"); 224 } 225 } 226 227 /** 228 * Return a string for the EGL error code, or the hex representation 229 * if the error is unknown. 230 * 231 * @param error The EGL error to convert into a String. 232 * 233 * @return An error string corresponding to the EGL error code. 234 */ 235 public static String getEGLErrorString(int error) { 236 switch (error) { 237 case EGL10.EGL_SUCCESS: 238 return "EGL_SUCCESS"; 239 case EGL10.EGL_NOT_INITIALIZED: 240 return "EGL_NOT_INITIALIZED"; 241 case EGL10.EGL_BAD_ACCESS: 242 return "EGL_BAD_ACCESS"; 243 case EGL10.EGL_BAD_ALLOC: 244 return "EGL_BAD_ALLOC"; 245 case EGL10.EGL_BAD_ATTRIBUTE: 246 return "EGL_BAD_ATTRIBUTE"; 247 case EGL10.EGL_BAD_CONFIG: 248 return "EGL_BAD_CONFIG"; 249 case EGL10.EGL_BAD_CONTEXT: 250 return "EGL_BAD_CONTEXT"; 251 case EGL10.EGL_BAD_CURRENT_SURFACE: 252 return "EGL_BAD_CURRENT_SURFACE"; 253 case EGL10.EGL_BAD_DISPLAY: 254 return "EGL_BAD_DISPLAY"; 255 case EGL10.EGL_BAD_MATCH: 256 return "EGL_BAD_MATCH"; 257 case EGL10.EGL_BAD_NATIVE_PIXMAP: 258 return "EGL_BAD_NATIVE_PIXMAP"; 259 case EGL10.EGL_BAD_NATIVE_WINDOW: 260 return "EGL_BAD_NATIVE_WINDOW"; 261 case EGL10.EGL_BAD_PARAMETER: 262 return "EGL_BAD_PARAMETER"; 263 case EGL10.EGL_BAD_SURFACE: 264 return "EGL_BAD_SURFACE"; 265 case EGL11.EGL_CONTEXT_LOST: 266 return "EGL_CONTEXT_LOST"; 267 default: 268 return "0x" + Integer.toHexString(error); 269 } 270 } 271 272 native private static void nativeClassInit(); 273 274 native private static int native_getInternalFormat(Bitmap bitmap); 275 native private static int native_getType(Bitmap bitmap); 276 native private static int native_texImage2D(int target, int level, int internalformat, 277 Bitmap bitmap, int type, int border); 278 native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset, 279 Bitmap bitmap, int format, int type); 280} 281