content: /*
   * Copyright (C) 2007 The Android Open Source Project
   * 
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
   * License. You may obtain a copy of the License at
   * 
   * http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
   * governing permissions and limitations under the License.
   */
  
  package com.badlogic.gdx.backends.android.surfaceview;
  
  import java.io.IOException;
  import java.io.Writer;
  import java.nio.Buffer;
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.CharBuffer;
  import java.nio.DoubleBuffer;
  import java.nio.FloatBuffer;
  import java.nio.IntBuffer;
  import java.nio.LongBuffer;
  import java.nio.ShortBuffer;
  import java.util.Arrays;
  
  import javax.microedition.khronos.opengles.GL;
  
  /**
   * A wrapper that logs all GL calls (and results) in human-readable form.
   * 
   */
  class GLLogWrapper extends GLWrapperBase {
  	private static final int FORMAT_INT = 0;
  	private static final int FORMAT_FLOAT = 1;
  	private static final int FORMAT_FIXED = 2;
  
  	public GLLogWrapper (GL gl, Writer log, boolean logArgumentNames) {
  		super(gl);
  		mLog = log;
  		mLogArgumentNames = logArgumentNames;
  	}
  
  	private void checkError () {
  		int glError;
  		if ((glError = mgl.glGetError()) != 0) {
  			String errorMessage = "glError: " + Integer.toString(glError);
  			logLine(errorMessage);
  		}
  	}
  
  	private void logLine (String message) {
  		log(message + '\n');
  	}
  
  	private void log (String message) {
  		try {
  			mLog.write(message);
  		} catch (IOException e) {
  			// Ignore exception, keep on trying
  		}
  	}
  
  	private void begin (String name) {
  		log(name + '(');
  		mArgCount = 0;
  	}
  
  	private void arg (String name, String value) {
  		if (mArgCount++ > 0) {
  			log(", ");
  		}
  		if (mLogArgumentNames) {
  			log(name + "=");
  		}
  		log(value);
  	}
  
  	private void end () {
  		log(");\n");
  		flush();
  	}
  
  	private void flush () {
  		try {
  			mLog.flush();
  		} catch (IOException e) {
  			mLog = null;
  		}
  	}
  
  	private void arg (String name, boolean value) {
  		arg(name, Boolean.toString(value));
  	}
  
  	private void arg (String name, int value) {
  		arg(name, Integer.toString(value));
  	}
  
  	private void arg (String name, float value) {
  		arg(name, Float.toString(value));
  	}
  
  	private void returns (String result) {
  		log(") returns " + result + ";\n");
  		flush();
  	}
  
  	private void returns (int result) {
  		returns(Integer.toString(result));
  	}
  
  	private void arg (String name, int n, int[] arr, int offset) {
  		arg(name, toString(n, FORMAT_INT, arr, offset));
  	}
  
  	private void arg (String name, int n, short[] arr, int offset) {
  		arg(name, toString(n, arr, offset));
  	}
  
  	private void arg (String name, int n, float[] arr, int offset) {
  		arg(name, toString(n, arr, offset));
  	}
  
  	private void formattedAppend (StringBuilder buf, int value, int format) {
  		switch (format) {
  		case FORMAT_INT:
  			buf.append(value);
  			break;
  		case FORMAT_FLOAT:
  			buf.append(Float.intBitsToFloat(value));
  			break;
  		case FORMAT_FIXED:
  			buf.append(value / 65536.0f);
  			break;
  		}
  	}
  
  	private String toString (int n, int format, int[] arr, int offset) {
  		StringBuilder buf = new StringBuilder();
  		buf.append("{\n");
  		int arrLen = arr.length;
  		for (int i = 0; i < n; i++) {
  			int index = offset + i;
  			buf.append(" [" + index + "] = ");
  			if (index < 0 || index >= arrLen) {
  				buf.append("out of bounds");
  			} else {
  				formattedAppend(buf, arr[index], format);
  			}
  			buf.append('\n');
  		}
  		buf.append("}");
  		return buf.toString();
  	}
  
  	private String toString (int n, short[] arr, int offset) {
  		StringBuilder buf = new StringBuilder();
  		buf.append("{\n");
  		int arrLen = arr.length;
  		for (int i = 0; i < n; i++) {
  			int index = offset + i;
  			buf.append(" [" + index + "] = ");
  			if (index < 0 || index >= arrLen) {
  				buf.append("out of bounds");
  			} else {
  				buf.append(arr[index]);
  			}
  			buf.append('\n');
  		}
  		buf.append("}");
  		return buf.toString();
  	}
  
  	private String toString (int n, float[] arr, int offset) {
  		StringBuilder buf = new StringBuilder();
  		buf.append("{\n");
  		int arrLen = arr.length;
  		for (int i = 0; i < n; i++) {
  			int index = offset + i;
  			buf.append("[" + index + "] = ");
  			if (index < 0 || index >= arrLen) {
  				buf.append("out of bounds");
  			} else {
  				buf.append(arr[index]);
  			}
  			buf.append('\n');
  		}
  		buf.append("}");
  		return buf.toString();
  	}
  
  	private String toString (int n, FloatBuffer buf) {
  		StringBuilder builder = new StringBuilder();
  		builder.append("{\n");
  		for (int i = 0; i < n; i++) {
  			builder.append(" [" + i + "] = " + buf.get(i) + '\n');
  		}
  		builder.append("}");
  		return builder.toString();
  	}
  
  	private String toString (int n, int format, IntBuffer buf) {
  		StringBuilder builder = new StringBuilder();
  		builder.append("{\n");
  		for (int i = 0; i < n; i++) {
  			builder.append(" [" + i + "] = ");
  			formattedAppend(builder, buf.get(i), format);
  			builder.append('\n');
  		}
  		builder.append("}");
  		return builder.toString();
  	}
  
  	private String toString (int n, ShortBuffer buf) {
  		StringBuilder builder = new StringBuilder();
  		builder.append("{\n");
  		for (int i = 0; i < n; i++) {
  			builder.append(" [" + i + "] = " + buf.get(i) + '\n');
  		}
  		builder.append("}");
  		return builder.toString();
  	}
  
  	private void arg (String name, int n, FloatBuffer buf) {
  		arg(name, toString(n, buf));
  	}
  
  	private void arg (String name, int n, IntBuffer buf) {
  		arg(name, toString(n, FORMAT_INT, buf));
  	}
  
  	private void arg (String name, int n, ShortBuffer buf) {
  		arg(name, toString(n, buf));
  	}
  
  	private void argPointer (int size, int type, int stride, Buffer pointer) {
  		arg("size", size);
  		arg("type", getPointerTypeName(type));
  		arg("stride", stride);
  		arg("pointer", pointer.toString());
  	}
  
  	private static String getHex (int value) {
  		return "0x" + Integer.toHexString(value);
  	}
  
  	public static String getErrorString (int error) {
  		switch (error) {
  		case GL_NO_ERROR:
  			return "GL_NO_ERROR";
  		case GL_INVALID_ENUM:
  			return "GL_INVALID_ENUM";
  		case GL_INVALID_VALUE:
  			return "GL_INVALID_VALUE";
  		case GL_INVALID_OPERATION:
  			return "GL_INVALID_OPERATION";
  		case GL_STACK_OVERFLOW:
  			return "GL_STACK_OVERFLOW";
  		case GL_STACK_UNDERFLOW:
  			return "GL_STACK_UNDERFLOW";
  		case GL_OUT_OF_MEMORY:
  			return "GL_OUT_OF_MEMORY";
  		default:
  			return getHex(error);
  		}
  	}
  
  	private String getClearBufferMask (int mask) {
  		StringBuilder b = new StringBuilder();
  		if ((mask & GL_DEPTH_BUFFER_BIT) != 0) {
  			b.append("GL_DEPTH_BUFFER_BIT");
  			mask &= ~GL_DEPTH_BUFFER_BIT;
  		}
  		if ((mask & GL_STENCIL_BUFFER_BIT) != 0) {
  			if (b.length() > 0) {
  				b.append(" | ");
  			}
  			b.append("GL_STENCIL_BUFFER_BIT");
  			mask &= ~GL_STENCIL_BUFFER_BIT;
  		}
  		if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
  			if (b.length() > 0) {
  				b.append(" | ");
  			}
  			b.append("GL_COLOR_BUFFER_BIT");
  			mask &= ~GL_COLOR_BUFFER_BIT;
  		}
  		if (mask != 0) {
  			if (b.length() > 0) {
  				b.append(" | ");
  			}
  			b.append(getHex(mask));
  		}
  		return b.toString();
  	}
  
  	private String getFactor (int factor) {
  		switch (factor) {
  		case GL_ZERO:
  			return "GL_ZERO";
  		case GL_ONE:
  			return "GL_ONE";
  		case GL_SRC_COLOR:
  			return "GL_SRC_COLOR";
  		case GL_ONE_MINUS_SRC_COLOR:
  			return "GL_ONE_MINUS_SRC_COLOR";
  		case GL_DST_COLOR:
  			return "GL_DST_COLOR";
  		case GL_ONE_MINUS_DST_COLOR:
  			return "GL_ONE_MINUS_DST_COLOR";
  		case GL_SRC_ALPHA:
  			return "GL_SRC_ALPHA";
  		case GL_ONE_MINUS_SRC_ALPHA:
  			return "GL_ONE_MINUS_SRC_ALPHA";
  		case GL_DST_ALPHA:
  			return "GL_DST_ALPHA";
  		case GL_ONE_MINUS_DST_ALPHA:
  			return "GL_ONE_MINUS_DST_ALPHA";
  		case GL_SRC_ALPHA_SATURATE:
  			return "GL_SRC_ALPHA_SATURATE";
  
  		default:
  			return getHex(factor);
  		}
  	}
  
  	private String getShadeModel (int model) {
  		switch (model) {
  		case GL_FLAT:
  			return "GL_FLAT";
  		case GL_SMOOTH:
  			return "GL_SMOOTH";
  		default:
  			return getHex(model);
  		}
  	}
  
  	private String getTextureTarget (int target) {
  		switch (target) {
  		case GL_TEXTURE_2D:
  			return "GL_TEXTURE_2D";
  		default:
  			return getHex(target);
  		}
  	}
  
  	private String getTextureEnvTarget (int target) {
  		switch (target) {
  		case GL_TEXTURE_ENV:
  			return "GL_TEXTURE_ENV";
  		default:
  			return getHex(target);
  		}
  	}
  
  	private String getTextureEnvPName (int pname) {
  		switch (pname) {
  		case GL_TEXTURE_ENV_MODE:
  			return "GL_TEXTURE_ENV_MODE";
  		case GL_TEXTURE_ENV_COLOR:
  			return "GL_TEXTURE_ENV_COLOR";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getTextureEnvParamCount (int pname) {
  		switch (pname) {
  		case GL_TEXTURE_ENV_MODE:
  			return 1;
  		case GL_TEXTURE_ENV_COLOR:
  			return 4;
  		default:
  			return 0;
  		}
  	}
  
  	private String getTextureEnvParamName (float param) {
  		int iparam = (int)param;
  		if (param == (float)iparam) {
  			switch (iparam) {
  			case GL_REPLACE:
  				return "GL_REPLACE";
  			case GL_MODULATE:
  				return "GL_MODULATE";
  			case GL_DECAL:
  				return "GL_DECAL";
  			case GL_BLEND:
  				return "GL_BLEND";
  			case GL_ADD:
  				return "GL_ADD";
  			case GL_COMBINE:
  				return "GL_COMBINE";
  			default:
  				return getHex(iparam);
  			}
  		}
  		return Float.toString(param);
  	}
  
  	private String getMatrixMode (int matrixMode) {
  		switch (matrixMode) {
  		case GL_MODELVIEW:
  			return "GL_MODELVIEW";
  		case GL_PROJECTION:
  			return "GL_PROJECTION";
  		case GL_TEXTURE:
  			return "GL_TEXTURE";
  		default:
  			return getHex(matrixMode);
  		}
  	}
  
  	private String getClientState (int clientState) {
  		switch (clientState) {
  		case GL_COLOR_ARRAY:
  			return "GL_COLOR_ARRAY";
  		case GL_VERTEX_ARRAY:
  			return "GL_VERTEX_ARRAY";
  		case GL_NORMAL_ARRAY:
  			return "GL_NORMAL_ARRAY";
  		case GL_TEXTURE_COORD_ARRAY:
  			return "GL_TEXTURE_COORD_ARRAY";
  		default:
  			return getHex(clientState);
  		}
  	}
  
  	private String getCap (int cap) {
  		switch (cap) {
  		case GL_FOG:
  			return "GL_FOG";
  		case GL_LIGHTING:
  			return "GL_LIGHTING";
  		case GL_TEXTURE_2D:
  			return "GL_TEXTURE_2D";
  		case GL_CULL_FACE:
  			return "GL_CULL_FACE";
  		case GL_ALPHA_TEST:
  			return "GL_ALPHA_TEST";
  		case GL_BLEND:
  			return "GL_BLEND";
  		case GL_COLOR_LOGIC_OP:
  			return "GL_COLOR_LOGIC_OP";
  		case GL_DITHER:
  			return "GL_DITHER";
  		case GL_STENCIL_TEST:
  			return "GL_STENCIL_TEST";
  		case GL_DEPTH_TEST:
  			return "GL_DEPTH_TEST";
  		case GL_LIGHT0:
  			return "GL_LIGHT0";
  		case GL_LIGHT1:
  			return "GL_LIGHT1";
  		case GL_LIGHT2:
  			return "GL_LIGHT2";
  		case GL_LIGHT3:
  			return "GL_LIGHT3";
  		case GL_LIGHT4:
  			return "GL_LIGHT4";
  		case GL_LIGHT5:
  			return "GL_LIGHT5";
  		case GL_LIGHT6:
  			return "GL_LIGHT6";
  		case GL_LIGHT7:
  			return "GL_LIGHT7";
  		case GL_POINT_SMOOTH:
  			return "GL_POINT_SMOOTH";
  		case GL_LINE_SMOOTH:
  			return "GL_LINE_SMOOTH";
  		case GL_COLOR_MATERIAL:
  			return "GL_COLOR_MATERIAL";
  		case GL_NORMALIZE:
  			return "GL_NORMALIZE";
  		case GL_RESCALE_NORMAL:
  			return "GL_RESCALE_NORMAL";
  		case GL_VERTEX_ARRAY:
  			return "GL_VERTEX_ARRAY";
  		case GL_NORMAL_ARRAY:
  			return "GL_NORMAL_ARRAY";
  		case GL_COLOR_ARRAY:
  			return "GL_COLOR_ARRAY";
  		case GL_TEXTURE_COORD_ARRAY:
  			return "GL_TEXTURE_COORD_ARRAY";
  		case GL_MULTISAMPLE:
  			return "GL_MULTISAMPLE";
  		case GL_SAMPLE_ALPHA_TO_COVERAGE:
  			return "GL_SAMPLE_ALPHA_TO_COVERAGE";
  		case GL_SAMPLE_ALPHA_TO_ONE:
  			return "GL_SAMPLE_ALPHA_TO_ONE";
  		case GL_SAMPLE_COVERAGE:
  			return "GL_SAMPLE_COVERAGE";
  		case GL_SCISSOR_TEST:
  			return "GL_SCISSOR_TEST";
  		default:
  			return getHex(cap);
  		}
  	}
  
  	private String getTexturePName (int pname) {
  		switch (pname) {
  		case GL_TEXTURE_MAG_FILTER:
  			return "GL_TEXTURE_MAG_FILTER";
  		case GL_TEXTURE_MIN_FILTER:
  			return "GL_TEXTURE_MIN_FILTER";
  		case GL_TEXTURE_WRAP_S:
  			return "GL_TEXTURE_WRAP_S";
  		case GL_TEXTURE_WRAP_T:
  			return "GL_TEXTURE_WRAP_T";
  		case GL_GENERATE_MIPMAP:
  			return "GL_GENERATE_MIPMAP";
  		case GL_TEXTURE_CROP_RECT_OES:
  			return "GL_TEXTURE_CROP_RECT_OES";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private String getTextureParamName (float param) {
  		int iparam = (int)param;
  		if (param == (float)iparam) {
  			switch (iparam) {
  			case GL_CLAMP_TO_EDGE:
  				return "GL_CLAMP_TO_EDGE";
  			case GL_REPEAT:
  				return "GL_REPEAT";
  			case GL_NEAREST:
  				return "GL_NEAREST";
  			case GL_LINEAR:
  				return "GL_LINEAR";
  			case GL_NEAREST_MIPMAP_NEAREST:
  				return "GL_NEAREST_MIPMAP_NEAREST";
  			case GL_LINEAR_MIPMAP_NEAREST:
  				return "GL_LINEAR_MIPMAP_NEAREST";
  			case GL_NEAREST_MIPMAP_LINEAR:
  				return "GL_NEAREST_MIPMAP_LINEAR";
  			case GL_LINEAR_MIPMAP_LINEAR:
  				return "GL_LINEAR_MIPMAP_LINEAR";
  			default:
  				return getHex(iparam);
  			}
  		}
  		return Float.toString(param);
  	}
  
  	private String getFogPName (int pname) {
  		switch (pname) {
  		case GL_FOG_DENSITY:
  			return "GL_FOG_DENSITY";
  		case GL_FOG_START:
  			return "GL_FOG_START";
  		case GL_FOG_END:
  			return "GL_FOG_END";
  		case GL_FOG_MODE:
  			return "GL_FOG_MODE";
  		case GL_FOG_COLOR:
  			return "GL_FOG_COLOR";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getFogParamCount (int pname) {
  		switch (pname) {
  		case GL_FOG_DENSITY:
  			return 1;
  		case GL_FOG_START:
  			return 1;
  		case GL_FOG_END:
  			return 1;
  		case GL_FOG_MODE:
  			return 1;
  		case GL_FOG_COLOR:
  			return 4;
  		default:
  			return 0;
  		}
  	}
  
  	private String getBeginMode (int mode) {
  		switch (mode) {
  		case GL_POINTS:
  			return "GL_POINTS";
  		case GL_LINES:
  			return "GL_LINES";
  		case GL_LINE_LOOP:
  			return "GL_LINE_LOOP";
  		case GL_LINE_STRIP:
  			return "GL_LINE_STRIP";
  		case GL_TRIANGLES:
  			return "GL_TRIANGLES";
  		case GL_TRIANGLE_STRIP:
  			return "GL_TRIANGLE_STRIP";
  		case GL_TRIANGLE_FAN:
  			return "GL_TRIANGLE_FAN";
  		default:
  			return getHex(mode);
  		}
  	}
  
  	private String getIndexType (int type) {
  		switch (type) {
  		case GL_UNSIGNED_SHORT:
  			return "GL_UNSIGNED_SHORT";
  		case GL_UNSIGNED_BYTE:
  			return "GL_UNSIGNED_BYTE";
  		default:
  			return getHex(type);
  		}
  	}
  
  	private String getIntegerStateName (int pname) {
  		switch (pname) {
  		case GL_ALPHA_BITS:
  			return "GL_ALPHA_BITS";
  		case GL_ALIASED_LINE_WIDTH_RANGE:
  			return "GL_ALIASED_LINE_WIDTH_RANGE";
  		case GL_ALIASED_POINT_SIZE_RANGE:
  			return "GL_ALIASED_POINT_SIZE_RANGE";
  		case GL_BLUE_BITS:
  			return "GL_BLUE_BITS";
  		case GL_COMPRESSED_TEXTURE_FORMATS:
  			return "GL_COMPRESSED_TEXTURE_FORMATS";
  		case GL_DEPTH_BITS:
  			return "GL_DEPTH_BITS";
  		case GL_GREEN_BITS:
  			return "GL_GREEN_BITS";
  		case GL_MAX_ELEMENTS_INDICES:
  			return "GL_MAX_ELEMENTS_INDICES";
  		case GL_MAX_ELEMENTS_VERTICES:
  			return "GL_MAX_ELEMENTS_VERTICES";
  		case GL_MAX_LIGHTS:
  			return "GL_MAX_LIGHTS";
  		case GL_MAX_TEXTURE_SIZE:
  			return "GL_MAX_TEXTURE_SIZE";
  		case GL_MAX_VIEWPORT_DIMS:
  			return "GL_MAX_VIEWPORT_DIMS";
  		case GL_MAX_MODELVIEW_STACK_DEPTH:
  			return "GL_MAX_MODELVIEW_STACK_DEPTH";
  		case GL_MAX_PROJECTION_STACK_DEPTH:
  			return "GL_MAX_PROJECTION_STACK_DEPTH";
  		case GL_MAX_TEXTURE_STACK_DEPTH:
  			return "GL_MAX_TEXTURE_STACK_DEPTH";
  		case GL_MAX_TEXTURE_UNITS:
  			return "GL_MAX_TEXTURE_UNITS";
  		case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
  			return "GL_NUM_COMPRESSED_TEXTURE_FORMATS";
  		case GL_RED_BITS:
  			return "GL_RED_BITS";
  		case GL_SMOOTH_LINE_WIDTH_RANGE:
  			return "GL_SMOOTH_LINE_WIDTH_RANGE";
  		case GL_SMOOTH_POINT_SIZE_RANGE:
  			return "GL_SMOOTH_POINT_SIZE_RANGE";
  		case GL_STENCIL_BITS:
  			return "GL_STENCIL_BITS";
  		case GL_SUBPIXEL_BITS:
  			return "GL_SUBPIXEL_BITS";
  
  		case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
  			return "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES";
  		case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
  			return "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES";
  		case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
  			return "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES";
  
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getIntegerStateSize (int pname) {
  		switch (pname) {
  		case GL_ALPHA_BITS:
  			return 1;
  		case GL_ALIASED_LINE_WIDTH_RANGE:
  			return 2;
  		case GL_ALIASED_POINT_SIZE_RANGE:
  			return 2;
  		case GL_BLUE_BITS:
  			return 1;
  		case GL_COMPRESSED_TEXTURE_FORMATS:
  			// Have to ask the implementation for the size
  		{
  			int[] buffer = new int[1];
  			mgl.glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, buffer, 0);
  			return buffer[0];
  		}
  		case GL_DEPTH_BITS:
  			return 1;
  		case GL_GREEN_BITS:
  			return 1;
  		case GL_MAX_ELEMENTS_INDICES:
  			return 1;
  		case GL_MAX_ELEMENTS_VERTICES:
  			return 1;
  		case GL_MAX_LIGHTS:
  			return 1;
  		case GL_MAX_TEXTURE_SIZE:
  			return 1;
  		case GL_MAX_VIEWPORT_DIMS:
  			return 2;
  		case GL_MAX_MODELVIEW_STACK_DEPTH:
  			return 1;
  		case GL_MAX_PROJECTION_STACK_DEPTH:
  			return 1;
  		case GL_MAX_TEXTURE_STACK_DEPTH:
  			return 1;
  		case GL_MAX_TEXTURE_UNITS:
  			return 1;
  		case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
  			return 1;
  		case GL_RED_BITS:
  			return 1;
  		case GL_SMOOTH_LINE_WIDTH_RANGE:
  			return 2;
  		case GL_SMOOTH_POINT_SIZE_RANGE:
  			return 2;
  		case GL_STENCIL_BITS:
  			return 1;
  		case GL_SUBPIXEL_BITS:
  			return 1;
  
  		case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
  		case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
  		case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
  			return 16;
  
  		default:
  			return 0;
  		}
  	}
  
  	private int getIntegerStateFormat (int pname) {
  		switch (pname) {
  		case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
  		case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
  		case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
  			return FORMAT_FLOAT;
  
  		default:
  			return FORMAT_INT;
  		}
  	}
  
  	private String getHintTarget (int target) {
  		switch (target) {
  		case GL_FOG_HINT:
  			return "GL_FOG_HINT";
  		case GL_LINE_SMOOTH_HINT:
  			return "GL_LINE_SMOOTH_HINT";
  		case GL_PERSPECTIVE_CORRECTION_HINT:
  			return "GL_PERSPECTIVE_CORRECTION_HINT";
  		case GL_POINT_SMOOTH_HINT:
  			return "GL_POINT_SMOOTH_HINT";
  		case GL_POLYGON_SMOOTH_HINT:
  			return "GL_POLYGON_SMOOTH_HINT";
  		case GL_GENERATE_MIPMAP_HINT:
  			return "GL_GENERATE_MIPMAP_HINT";
  		default:
  			return getHex(target);
  		}
  	}
  
  	private String getHintMode (int mode) {
  		switch (mode) {
  		case GL_FASTEST:
  			return "GL_FASTEST";
  		case GL_NICEST:
  			return "GL_NICEST";
  		case GL_DONT_CARE:
  			return "GL_DONT_CARE";
  		default:
  			return getHex(mode);
  		}
  	}
  
  	private String getFaceName (int face) {
  		switch (face) {
  		case GL_FRONT_AND_BACK:
  			return "GL_FRONT_AND_BACK";
  		default:
  			return getHex(face);
  		}
  	}
  
  	private String getMaterialPName (int pname) {
  		switch (pname) {
  		case GL_AMBIENT:
  			return "GL_AMBIENT";
  		case GL_DIFFUSE:
  			return "GL_DIFFUSE";
  		case GL_SPECULAR:
  			return "GL_SPECULAR";
  		case GL_EMISSION:
  			return "GL_EMISSION";
  		case GL_SHININESS:
  			return "GL_SHININESS";
  		case GL_AMBIENT_AND_DIFFUSE:
  			return "GL_AMBIENT_AND_DIFFUSE";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getMaterialParamCount (int pname) {
  		switch (pname) {
  		case GL_AMBIENT:
  			return 4;
  		case GL_DIFFUSE:
  			return 4;
  		case GL_SPECULAR:
  			return 4;
  		case GL_EMISSION:
  			return 4;
  		case GL_SHININESS:
  			return 1;
  		case GL_AMBIENT_AND_DIFFUSE:
  			return 4;
  		default:
  			return 0;
  		}
  	}
  
  	private String getLightName (int light) {
  		if (light >= GL_LIGHT0 && light <= GL_LIGHT7) {
  			return "GL_LIGHT" + Integer.toString(light);
  		}
  		return getHex(light);
  	}
  
  	private String getLightPName (int pname) {
  		switch (pname) {
  		case GL_AMBIENT:
  			return "GL_AMBIENT";
  		case GL_DIFFUSE:
  			return "GL_DIFFUSE";
  		case GL_SPECULAR:
  			return "GL_SPECULAR";
  		case GL_POSITION:
  			return "GL_POSITION";
  		case GL_SPOT_DIRECTION:
  			return "GL_SPOT_DIRECTION";
  		case GL_SPOT_EXPONENT:
  			return "GL_SPOT_EXPONENT";
  		case GL_SPOT_CUTOFF:
  			return "GL_SPOT_CUTOFF";
  		case GL_CONSTANT_ATTENUATION:
  			return "GL_CONSTANT_ATTENUATION";
  		case GL_LINEAR_ATTENUATION:
  			return "GL_LINEAR_ATTENUATION";
  		case GL_QUADRATIC_ATTENUATION:
  			return "GL_QUADRATIC_ATTENUATION";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getLightParamCount (int pname) {
  		switch (pname) {
  		case GL_AMBIENT:
  			return 4;
  		case GL_DIFFUSE:
  			return 4;
  		case GL_SPECULAR:
  			return 4;
  		case GL_POSITION:
  			return 4;
  		case GL_SPOT_DIRECTION:
  			return 3;
  		case GL_SPOT_EXPONENT:
  			return 1;
  		case GL_SPOT_CUTOFF:
  			return 1;
  		case GL_CONSTANT_ATTENUATION:
  			return 1;
  		case GL_LINEAR_ATTENUATION:
  			return 1;
  		case GL_QUADRATIC_ATTENUATION:
  			return 1;
  		default:
  			return 0;
  		}
  	}
  
  	private String getLightModelPName (int pname) {
  		switch (pname) {
  		case GL_LIGHT_MODEL_AMBIENT:
  			return "GL_LIGHT_MODEL_AMBIENT";
  		case GL_LIGHT_MODEL_TWO_SIDE:
  			return "GL_LIGHT_MODEL_TWO_SIDE";
  		default:
  			return getHex(pname);
  		}
  	}
  
  	private int getLightModelParamCount (int pname) {
  		switch (pname) {
  		case GL_LIGHT_MODEL_AMBIENT:
  			return 4;
  		case GL_LIGHT_MODEL_TWO_SIDE:
  			return 1;
  		default:
  			return 0;
  		}
  	}
  
  	private String getPointerTypeName (int type) {
  		switch (type) {
  		case GL_BYTE:
  			return "GL_BYTE";
  		case GL_UNSIGNED_BYTE:
  			return "GL_UNSIGNED_BYTE";
  		case GL_SHORT:
  			return "GL_SHORT";
  		case GL_FIXED:
  			return "GL_FIXED";
  		case GL_FLOAT:
  			return "GL_FLOAT";
  		default:
  			return getHex(type);
  		}
  	}
  
  	ByteBuffer toByteBuffer (int byteCount, Buffer input) {
  		ByteBuffer result = null;
  		boolean convertWholeBuffer = (byteCount < 0);
  		if (input instanceof ByteBuffer) {
  			ByteBuffer input2 = (ByteBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit();
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			int position = input2.position();
  			for (int i = 0; i < byteCount; i++) {
  				result.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof CharBuffer) {
  			CharBuffer input2 = (CharBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 2;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			CharBuffer result2 = result.asCharBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 2; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof ShortBuffer) {
  			ShortBuffer input2 = (ShortBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 2;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			ShortBuffer result2 = result.asShortBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 2; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof IntBuffer) {
  			IntBuffer input2 = (IntBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 4;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			IntBuffer result2 = result.asIntBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 4; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof FloatBuffer) {
  			FloatBuffer input2 = (FloatBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 4;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			FloatBuffer result2 = result.asFloatBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 4; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof DoubleBuffer) {
  			DoubleBuffer input2 = (DoubleBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 8;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			DoubleBuffer result2 = result.asDoubleBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 8; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else if (input instanceof LongBuffer) {
  			LongBuffer input2 = (LongBuffer)input;
  			if (convertWholeBuffer) {
  				byteCount = input2.limit() * 8;
  			}
  			result = ByteBuffer.allocate(byteCount).order(input2.order());
  			LongBuffer result2 = result.asLongBuffer();
  			int position = input2.position();
  			for (int i = 0; i < byteCount / 8; i++) {
  				result2.put(input2.get());
  			}
  			input2.position(position);
  		} else {
  			throw new RuntimeException("Unimplemented Buffer subclass.");
  		}
  		result.rewind();
  		// The OpenGL API will interpret the result in hardware byte order,
  		// so we better do that as well:
  		result.order(ByteOrder.nativeOrder());
  		return result;
  	}
  
  	private char[] toCharIndices (int count, int type, Buffer indices) {
  		char[] result = new char[count];
  		switch (type) {
  		case GL_UNSIGNED_BYTE: {
  			ByteBuffer byteBuffer = toByteBuffer(count, indices);
  			byte[] array = byteBuffer.array();
  			int offset = byteBuffer.arrayOffset();
  			for (int i = 0; i < count; i++) {
  				result[i] = (char)(0xff & array[offset + i]);
  			}
  		}
  			break;
  		case GL_UNSIGNED_SHORT: {
  			CharBuffer charBuffer;
  			if (indices instanceof CharBuffer) {
  				charBuffer = (CharBuffer)indices;
  			} else {
  				ByteBuffer byteBuffer = toByteBuffer(count * 2, indices);
  				charBuffer = byteBuffer.asCharBuffer();
  			}
  			int oldPosition = charBuffer.position();
  			charBuffer.position(0);
  			charBuffer.get(result);
  			charBuffer.position(oldPosition);
  		}
  			break;
  		default:
  			// Don't throw an exception, because we don't want logging to
  			// change the behavior.
  			break;
  		}
  		return result;
  	}
  
  	private void doArrayElement (StringBuilder builder, boolean enabled, String name, PointerInfo pointer, int index) {
  		if (!enabled) {
  			return;
  		}
  		builder.append(" ");
  		builder.append(name + ":{");
  		if (pointer == null) {
  			builder.append("undefined");
  			return;
  		}
  		if (pointer.mStride < 0) {
  			builder.append("invalid stride");
  			return;
  		}
  
  		int stride = pointer.getStride();
  		ByteBuffer byteBuffer = pointer.mTempByteBuffer;
  		int size = pointer.mSize;
  		int type = pointer.mType;
  		int sizeofType = pointer.sizeof(type);
  		int byteOffset = stride * index;
  		for (int i = 0; i < size; i++) {
  			if (i > 0) {
  				builder.append(", ");
  			}
  			switch (type) {
  			case GL_BYTE: {
  				byte d = byteBuffer.get(byteOffset);
  				builder.append(Integer.toString(d));
  			}
  				break;
  			case GL_UNSIGNED_BYTE: {
  				byte d = byteBuffer.get(byteOffset);
  				builder.append(Integer.toString(0xff & d));
  			}
  				break;
  			case GL_SHORT: {
  				ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
  				short d = shortBuffer.get(byteOffset / 2);
  				builder.append(Integer.toString(d));
  			}
  				break;
  			case GL_FIXED: {
  				IntBuffer intBuffer = byteBuffer.asIntBuffer();
  				int d = intBuffer.get(byteOffset / 4);
  				builder.append(Integer.toString(d));
  			}
  				break;
  			case GL_FLOAT: {
  				FloatBuffer intBuffer = byteBuffer.asFloatBuffer();
  				float d = intBuffer.get(byteOffset / 4);
  				builder.append(Float.toString(d));
  			}
  				break;
  			default:
  				builder.append("?");
  				break;
  			}
  			byteOffset += sizeofType;
  		}
  		builder.append("}");
  	}
  
  	private void doElement (StringBuilder builder, int ordinal, int vertexIndex) {
  		builder.append(" [" + ordinal + " : " + vertexIndex + "] =");
  		doArrayElement(builder, mVertexArrayEnabled, "v", mVertexPointer, vertexIndex);
  		doArrayElement(builder, mNormalArrayEnabled, "n", mNormalPointer, vertexIndex);
  		doArrayElement(builder, mColorArrayEnabled, "c", mColorPointer, vertexIndex);
  		doArrayElement(builder, mTextureCoordArrayEnabled, "t", mTexCoordPointer, vertexIndex);
  		builder.append("\n");
  		// Vertex
  		// Normal
  		// Color
  		// TexCoord
  	}
  
  	private void bindArrays () {
  		if (mColorArrayEnabled) mColorPointer.bindByteBuffer();
  		if (mNormalArrayEnabled) mNormalPointer.bindByteBuffer();
  		if (mTextureCoordArrayEnabled) mTexCoordPointer.bindByteBuffer();
  		if (mVertexArrayEnabled) mVertexPointer.bindByteBuffer();
  	}
  
  	private void unbindArrays () {
  		if (mColorArrayEnabled) mColorPointer.unbindByteBuffer();
  		if (mNormalArrayEnabled) mNormalPointer.unbindByteBuffer();
  		if (mTextureCoordArrayEnabled) mTexCoordPointer.unbindByteBuffer();
  		if (mVertexArrayEnabled) mVertexPointer.unbindByteBuffer();
  	}
  
  	private void startLogIndices () {
  		mStringBuilder = new StringBuilder();
  		mStringBuilder.append("\n");
  		bindArrays();
  	}
  
  	private void endLogIndices () {
  		log(mStringBuilder.toString());
  		unbindArrays();
  	}
  
  	// ---------------------------------------------------------------------
  	// GL10 methods:
  
  	public void glActiveTexture (int texture) {
  		begin("glActiveTexture");
  		arg("texture", texture);
  		end();
  		mgl.glActiveTexture(texture);
  		checkError();
  	}
  
  	public void glAlphaFunc (int func, float ref) {
  		begin("glAlphaFunc");
  		arg("func", func);
  		arg("ref", ref);
  		end();
  		mgl.glAlphaFunc(func, ref);
  		checkError();
  	}
  
  	public void glAlphaFuncx (int func, int ref) {
  		begin("glAlphaFuncx");
  		arg("func", func);
  		arg("ref", ref);
  		end();
  		mgl.glAlphaFuncx(func, ref);
  		checkError();
  	}
  
  	public void glBindTexture (int target, int texture) {
  		begin("glBindTexture");
  		arg("target", getTextureTarget(target));
  		arg("texture", texture);
  		end();
  		mgl.glBindTexture(target, texture);
  		checkError();
  	}
  
  	public void glBlendFunc (int sfactor, int dfactor) {
  		begin("glBlendFunc");
  		arg("sfactor", getFactor(sfactor));
  		arg("dfactor", getFactor(dfactor));
  		end();
  
  		mgl.glBlendFunc(sfactor, dfactor);
  		checkError();
  	}
  
  	public void glClear (int mask) {
  		begin("glClear");
  		arg("mask", getClearBufferMask(mask));
  		end();
  
  		mgl.glClear(mask);
  		checkError();
  	}
  
  	public void glClearColor (float red, float green, float blue, float alpha) {
  		begin("glClearColor");
  		arg("red", red);
  		arg("green", green);
  		arg("blue", blue);
  		arg("alpha", alpha);
  		end();
  
  		mgl.glClearColor(red, green, blue, alpha);
  		checkError();
  	}
  
  	public void glClearColorx (int red, int green, int blue, int alpha) {
  		begin("glClearColor");
  		arg("red", red);
  		arg("green", green);
  		arg("blue", blue);
  		arg("alpha", alpha);
  		end();
  
  		mgl.glClearColorx(red, green, blue, alpha);
  		checkError();
  	}
  
  	public void glClearDepthf (float depth) {
  		begin("glClearDepthf");
  		arg("depth", depth);
  		end();
  
  		mgl.glClearDepthf(depth);
  		checkError();
  	}
  
  	public void glClearDepthx (int depth) {
  		begin("glClearDepthx");
  		arg("depth", depth);
  		end();
  
  		mgl.glClearDepthx(depth);
  		checkError();
  	}
  
  	public void glClearStencil (int s) {
  		begin("glClearStencil");
  		arg("s", s);
  		end();
  
  		mgl.glClearStencil(s);
  		checkError();
  	}
  
  	public void glClientActiveTexture (int texture) {
  		begin("glClientActiveTexture");
  		arg("texture", texture);
  		end();
  
  		mgl.glClientActiveTexture(texture);
  		checkError();
  	}
  
  	public void glColor4f (float red, float green, float blue, float alpha) {
  		begin("glColor4f");
  		arg("red", red);
  		arg("green", green);
  		arg("blue", blue);
  		arg("alpha", alpha);
  		end();
  
  		mgl.glColor4f(red, green, blue, alpha);
  		checkError();
  	}
  
  	public void glColor4x (int red, int green, int blue, int alpha) {
  		begin("glColor4x");
  		arg("red", red);
  		arg("green", green);
  		arg("blue", blue);
  		arg("alpha", alpha);
  		end();
  
  		mgl.glColor4x(red, green, blue, alpha);
  		checkError();
  	}
  
  	public void glColorMask (boolean red, boolean green, boolean blue, boolean alpha) {
  		begin("glColorMask");
  		arg("red", red);
  		arg("green", green);
  		arg("blue", blue);
  		arg("alpha", alpha);
  		end();
  
  		mgl.glColorMask(red, green, blue, alpha);
  		checkError();
  	}
  
  	public void glColorPointer (int size, int type, int stride, Buffer pointer) {
  		begin("glColorPointer");
  		argPointer(size, type, stride, pointer);
  		end();
  		mColorPointer = new PointerInfo(size, type, stride, pointer);
  
  		mgl.glColorPointer(size, type, stride, pointer);
  		checkError();
  	}
  
  	public void glCompressedTexImage2D (int target, int level, int internalformat, int width, int height, int border,
  		int imageSize, Buffer data) {
  		begin("glCompressedTexImage2D");
  		arg("target", getTextureTarget(target));
  		arg("level", level);
  		arg("internalformat", internalformat);
  		arg("width", width);
  		arg("height", height);
  		arg("border", border);
  		arg("imageSize", imageSize);
  		arg("data", data.toString());
  		end();
  
  		mgl.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
  		checkError();
  	}
  
  	public void glCompressedTexSubImage2D (int target, int level, int xoffset, int yoffset, int width, int height, int format,
  		int imageSize, Buffer data) {
  		begin("glCompressedTexSubImage2D");
  		arg("target", getTextureTarget(target));
  		arg("level", level);
  		arg("xoffset", xoffset);
  		arg("yoffset", yoffset);
  		arg("width", width);
  		arg("height", height);
  		arg("format", format);
  		arg("imageSize", imageSize);
  		arg("data", data.toString());
  		end();
  
  		mgl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
  		checkError();
  	}
  
  	public void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border) {
  		begin("glCopyTexImage2D");
  		arg("target", getTextureTarget(target));
  		arg("level", level);
  		arg("internalformat", internalformat);
  		arg("x", x);
  		arg("y", y);
  		arg("width", width);
  		arg("height", height);
  		arg("border", border);
  		end();
  
  		mgl.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
  		checkError();
  	}
  
  	public void glCopyTexSubImage2D (int target, int level, int xoffset, int yoffset, int x, int y, int width, int height) {
  		begin("glCopyTexSubImage2D");
  		arg("target", getTextureTarget(target));
  		arg("level", level);
  		arg("xoffset", xoffset);
  		arg("yoffset", yoffset);
  		arg("x", x);
  		arg("y", y);
  		arg("width", width);
  		arg("height", height);
  		end();
  
  		mgl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
  		checkError();
  	}
  
  	public void glCullFace (int mode) {
  		begin("glCullFace");
  		arg("mode", mode);
  		end();
  
  		mgl.glCullFace(mode);
  		checkError();
  	}
  
  	public void glDeleteTextures (int n, int[] textures, int offset) {
  		begin("glDeleteTextures");
  		arg("n", n);
  		arg("textures", n, textures, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glDeleteTextures(n, textures, offset);
  		checkError();
  	}
  
  	public void glDeleteTextures (int n, IntBuffer textures) {
  		begin("glDeleteTextures");
  		arg("n", n);
  		arg("textures", n, textures);
  		end();
  
  		mgl.glDeleteTextures(n, textures);
  		checkError();
  	}
  
  	public void glDepthFunc (int func) {
  		begin("glDepthFunc");
  		arg("func", func);
  		end();
  
  		mgl.glDepthFunc(func);
  		checkError();
  	}
  
  	public void glDepthMask (boolean flag) {
  		begin("glDepthMask");
  		arg("flag", flag);
  		end();
  
  		mgl.glDepthMask(flag);
  		checkError();
  	}
  
  	public void glDepthRangef (float near, float far) {
  		begin("glDepthRangef");
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glDepthRangef(near, far);
  		checkError();
  	}
  
  	public void glDepthRangex (int near, int far) {
  		begin("glDepthRangex");
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glDepthRangex(near, far);
  		checkError();
  	}
  
  	public void glDisable (int cap) {
  		begin("glDisable");
  		arg("cap", getCap(cap));
  		end();
  
  		mgl.glDisable(cap);
  		checkError();
  	}
  
  	public void glDisableClientState (int array) {
  		begin("glDisableClientState");
  		arg("array", getClientState(array));
  		end();
  
  		switch (array) {
  		case GL_COLOR_ARRAY:
  			mColorArrayEnabled = false;
  			break;
  		case GL_NORMAL_ARRAY:
  			mNormalArrayEnabled = false;
  			break;
  		case GL_TEXTURE_COORD_ARRAY:
  			mTextureCoordArrayEnabled = false;
  			break;
  		case GL_VERTEX_ARRAY:
  			mVertexArrayEnabled = false;
  			break;
  		}
  		mgl.glDisableClientState(array);
  		checkError();
  	}
  
  	public void glDrawArrays (int mode, int first, int count) {
  		begin("glDrawArrays");
  		arg("mode", mode);
  		arg("first", first);
  		arg("count", count);
  		startLogIndices();
  		for (int i = 0; i < count; i++) {
  			doElement(mStringBuilder, i, first + i);
  		}
  		endLogIndices();
  		end();
  
  		mgl.glDrawArrays(mode, first, count);
  		checkError();
  	}
  
  	public void glDrawElements (int mode, int count, int type, Buffer indices) {
  		begin("glDrawElements");
  		arg("mode", getBeginMode(mode));
  		arg("count", count);
  		arg("type", getIndexType(type));
  		char[] indexArray = toCharIndices(count, type, indices);
  		int indexArrayLength = indexArray.length;
  		startLogIndices();
  		for (int i = 0; i < indexArrayLength; i++) {
  			doElement(mStringBuilder, i, indexArray[i]);
  		}
  		endLogIndices();
  		end();
  
  		mgl.glDrawElements(mode, count, type, indices);
  		checkError();
  	}
  
  	public void glEnable (int cap) {
  		begin("glEnable");
  		arg("cap", getCap(cap));
  		end();
  
  		mgl.glEnable(cap);
  		checkError();
  	}
  
  	public void glEnableClientState (int array) {
  		begin("glEnableClientState");
  		arg("array", getClientState(array));
  		end();
  
  		switch (array) {
  		case GL_COLOR_ARRAY:
  			mColorArrayEnabled = true;
  			break;
  		case GL_NORMAL_ARRAY:
  			mNormalArrayEnabled = true;
  			break;
  		case GL_TEXTURE_COORD_ARRAY:
  			mTextureCoordArrayEnabled = true;
  			break;
  		case GL_VERTEX_ARRAY:
  			mVertexArrayEnabled = true;
  			break;
  		}
  		mgl.glEnableClientState(array);
  		checkError();
  	}
  
  	public void glFinish () {
  		begin("glFinish");
  		end();
  
  		mgl.glFinish();
  		checkError();
  	}
  
  	public void glFlush () {
  		begin("glFlush");
  		end();
  
  		mgl.glFlush();
  		checkError();
  	}
  
  	public void glFogf (int pname, float param) {
  		begin("glFogf");
  		arg("pname", pname);
  		arg("param", param);
  		end();
  
  		mgl.glFogf(pname, param);
  		checkError();
  	}
  
  	public void glFogfv (int pname, float[] params, int offset) {
  		begin("glFogfv");
  		arg("pname", getFogPName(pname));
  		arg("params", getFogParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glFogfv(pname, params, offset);
  		checkError();
  	}
  
  	public void glFogfv (int pname, FloatBuffer params) {
  		begin("glFogfv");
  		arg("pname", getFogPName(pname));
  		arg("params", getFogParamCount(pname), params);
  		end();
  
  		mgl.glFogfv(pname, params);
  		checkError();
  	}
  
  	public void glFogx (int pname, int param) {
  		begin("glFogx");
  		arg("pname", getFogPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glFogx(pname, param);
  		checkError();
  	}
  
  	public void glFogxv (int pname, int[] params, int offset) {
  		begin("glFogxv");
  		arg("pname", getFogPName(pname));
  		arg("params", getFogParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glFogxv(pname, params, offset);
  		checkError();
  	}
  
  	public void glFogxv (int pname, IntBuffer params) {
  		begin("glFogxv");
  		arg("pname", getFogPName(pname));
  		arg("params", getFogParamCount(pname), params);
  		end();
  
  		mgl.glFogxv(pname, params);
  		checkError();
  	}
  
  	public void glFrontFace (int mode) {
  		begin("glFrontFace");
  		arg("mode", mode);
  		end();
  
  		mgl.glFrontFace(mode);
  		checkError();
  	}
  
  	public void glFrustumf (float left, float right, float bottom, float top, float near, float far) {
  		begin("glFrustumf");
  		arg("left", left);
  		arg("right", right);
  		arg("bottom", bottom);
  		arg("top", top);
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glFrustumf(left, right, bottom, top, near, far);
  		checkError();
  	}
  
  	public void glFrustumx (int left, int right, int bottom, int top, int near, int far) {
  		begin("glFrustumx");
  		arg("left", left);
  		arg("right", right);
  		arg("bottom", bottom);
  		arg("top", top);
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glFrustumx(left, right, bottom, top, near, far);
  		checkError();
  	}
  
  	public void glGenTextures (int n, int[] textures, int offset) {
  		begin("glGenTextures");
  		arg("n", n);
  		arg("textures", Arrays.toString(textures));
  		arg("offset", offset);
  
  		mgl.glGenTextures(n, textures, offset);
  
  		returns(toString(n, FORMAT_INT, textures, offset));
  
  		checkError();
  	}
  
  	public void glGenTextures (int n, IntBuffer textures) {
  		begin("glGenTextures");
  		arg("n", n);
  		arg("textures", textures.toString());
  
  		mgl.glGenTextures(n, textures);
  
  		returns(toString(n, FORMAT_INT, textures));
  
  		checkError();
  	}
  
  	public int glGetError () {
  		begin("glGetError");
  
  		int result = mgl.glGetError();
  
  		returns(result);
  
  		return result;
  	}
  
  	public void glGetIntegerv (int pname, int[] params, int offset) {
  		begin("glGetIntegerv");
  		arg("pname", getIntegerStateName(pname));
  		arg("params", Arrays.toString(params));
  		arg("offset", offset);
  
  		mgl.glGetIntegerv(pname, params, offset);
  
  		returns(toString(getIntegerStateSize(pname), getIntegerStateFormat(pname), params, offset));
  
  		checkError();
  	}
  
  	public void glGetIntegerv (int pname, IntBuffer params) {
  		begin("glGetIntegerv");
  		arg("pname", getIntegerStateName(pname));
  		arg("params", params.toString());
  
  		mgl.glGetIntegerv(pname, params);
  
  		returns(toString(getIntegerStateSize(pname), getIntegerStateFormat(pname), params));
  
  		checkError();
  	}
  
  	public String glGetString (int name) {
  		begin("glGetString");
  		arg("name", name);
  
  		String result = mgl.glGetString(name);
  
  		returns(result);
  
  		checkError();
  		return result;
  	}
  
  	public void glHint (int target, int mode) {
  		begin("glHint");
  		arg("target", getHintTarget(target));
  		arg("mode", getHintMode(mode));
  		end();
  
  		mgl.glHint(target, mode);
  		checkError();
  	}
  
  	public void glLightModelf (int pname, float param) {
  		begin("glLightModelf");
  		arg("pname", getLightModelPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glLightModelf(pname, param);
  		checkError();
  	}
  
  	public void glLightModelfv (int pname, float[] params, int offset) {
  		begin("glLightModelfv");
  		arg("pname", getLightModelPName(pname));
  		arg("params", getLightModelParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLightModelfv(pname, params, offset);
  		checkError();
  	}
  
  	public void glLightModelfv (int pname, FloatBuffer params) {
  		begin("glLightModelfv");
  		arg("pname", getLightModelPName(pname));
  		arg("params", getLightModelParamCount(pname), params);
  		end();
  
  		mgl.glLightModelfv(pname, params);
  		checkError();
  	}
  
  	public void glLightModelx (int pname, int param) {
  		begin("glLightModelx");
  		arg("pname", getLightModelPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glLightModelx(pname, param);
  		checkError();
  	}
  
  	public void glLightModelxv (int pname, int[] params, int offset) {
  		begin("glLightModelxv");
  		arg("pname", getLightModelPName(pname));
  		arg("params", getLightModelParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLightModelxv(pname, params, offset);
  		checkError();
  	}
  
  	public void glLightModelxv (int pname, IntBuffer params) {
  		begin("glLightModelfv");
  		arg("pname", getLightModelPName(pname));
  		arg("params", getLightModelParamCount(pname), params);
  		end();
  
  		mgl.glLightModelxv(pname, params);
  		checkError();
  	}
  
  	public void glLightf (int light, int pname, float param) {
  		begin("glLightf");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glLightf(light, pname, param);
  		checkError();
  	}
  
  	public void glLightfv (int light, int pname, float[] params, int offset) {
  		begin("glLightfv");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("params", getLightParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLightfv(light, pname, params, offset);
  		checkError();
  	}
  
  	public void glLightfv (int light, int pname, FloatBuffer params) {
  		begin("glLightfv");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("params", getLightParamCount(pname), params);
  		end();
  
  		mgl.glLightfv(light, pname, params);
  		checkError();
  	}
  
  	public void glLightx (int light, int pname, int param) {
  		begin("glLightx");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glLightx(light, pname, param);
  		checkError();
  	}
  
  	public void glLightxv (int light, int pname, int[] params, int offset) {
  		begin("glLightxv");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("params", getLightParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLightxv(light, pname, params, offset);
  		checkError();
  	}
  
  	public void glLightxv (int light, int pname, IntBuffer params) {
  		begin("glLightxv");
  		arg("light", getLightName(light));
  		arg("pname", getLightPName(pname));
  		arg("params", getLightParamCount(pname), params);
  		end();
  
  		mgl.glLightxv(light, pname, params);
  		checkError();
  	}
  
  	public void glLineWidth (float width) {
  		begin("glLineWidth");
  		arg("width", width);
  		end();
  
  		mgl.glLineWidth(width);
  		checkError();
  	}
  
  	public void glLineWidthx (int width) {
  		begin("glLineWidthx");
  		arg("width", width);
  		end();
  
  		mgl.glLineWidthx(width);
  		checkError();
  	}
  
  	public void glLoadIdentity () {
  		begin("glLoadIdentity");
  		end();
  
  		mgl.glLoadIdentity();
  		checkError();
  	}
  
  	public void glLoadMatrixf (float[] m, int offset) {
  		begin("glLoadMatrixf");
  		arg("m", 16, m, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLoadMatrixf(m, offset);
  		checkError();
  	}
  
  	public void glLoadMatrixf (FloatBuffer m) {
  		begin("glLoadMatrixf");
  		arg("m", 16, m);
  		end();
  
  		mgl.glLoadMatrixf(m);
  		checkError();
  	}
  
  	public void glLoadMatrixx (int[] m, int offset) {
  		begin("glLoadMatrixx");
  		arg("m", 16, m, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glLoadMatrixx(m, offset);
  		checkError();
  	}
  
  	public void glLoadMatrixx (IntBuffer m) {
  		begin("glLoadMatrixx");
  		arg("m", 16, m);
  		end();
  
  		mgl.glLoadMatrixx(m);
  		checkError();
  	}
  
  	public void glLogicOp (int opcode) {
  		begin("glLogicOp");
  		arg("opcode", opcode);
  		end();
  
  		mgl.glLogicOp(opcode);
  		checkError();
  	}
  
  	public void glMaterialf (int face, int pname, float param) {
  		begin("glMaterialf");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glMaterialf(face, pname, param);
  		checkError();
  	}
  
  	public void glMaterialfv (int face, int pname, float[] params, int offset) {
  		begin("glMaterialfv");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("params", getMaterialParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glMaterialfv(face, pname, params, offset);
  		checkError();
  	}
  
  	public void glMaterialfv (int face, int pname, FloatBuffer params) {
  		begin("glMaterialfv");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("params", getMaterialParamCount(pname), params);
  		end();
  
  		mgl.glMaterialfv(face, pname, params);
  		checkError();
  	}
  
  	public void glMaterialx (int face, int pname, int param) {
  		begin("glMaterialx");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glMaterialx(face, pname, param);
  		checkError();
  	}
  
  	public void glMaterialxv (int face, int pname, int[] params, int offset) {
  		begin("glMaterialxv");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("params", getMaterialParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glMaterialxv(face, pname, params, offset);
  		checkError();
  	}
  
  	public void glMaterialxv (int face, int pname, IntBuffer params) {
  		begin("glMaterialxv");
  		arg("face", getFaceName(face));
  		arg("pname", getMaterialPName(pname));
  		arg("params", getMaterialParamCount(pname), params);
  		end();
  
  		mgl.glMaterialxv(face, pname, params);
  		checkError();
  	}
  
  	public void glMatrixMode (int mode) {
  		begin("glMatrixMode");
  		arg("mode", getMatrixMode(mode));
  		end();
  
  		mgl.glMatrixMode(mode);
  		checkError();
  	}
  
  	public void glMultMatrixf (float[] m, int offset) {
  		begin("glMultMatrixf");
  		arg("m", 16, m, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glMultMatrixf(m, offset);
  		checkError();
  	}
  
  	public void glMultMatrixf (FloatBuffer m) {
  		begin("glMultMatrixf");
  		arg("m", 16, m);
  		end();
  
  		mgl.glMultMatrixf(m);
  		checkError();
  	}
  
  	public void glMultMatrixx (int[] m, int offset) {
  		begin("glMultMatrixx");
  		arg("m", 16, m, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glMultMatrixx(m, offset);
  		checkError();
  	}
  
  	public void glMultMatrixx (IntBuffer m) {
  		begin("glMultMatrixx");
  		arg("m", 16, m);
  		end();
  
  		mgl.glMultMatrixx(m);
  		checkError();
  	}
  
  	public void glMultiTexCoord4f (int target, float s, float t, float r, float q) {
  		begin("glMultiTexCoord4f");
  		arg("target", target);
  		arg("s", s);
  		arg("t", t);
  		arg("r", r);
  		arg("q", q);
  		end();
  
  		mgl.glMultiTexCoord4f(target, s, t, r, q);
  		checkError();
  	}
  
  	public void glMultiTexCoord4x (int target, int s, int t, int r, int q) {
  		begin("glMultiTexCoord4x");
  		arg("target", target);
  		arg("s", s);
  		arg("t", t);
  		arg("r", r);
  		arg("q", q);
  		end();
  
  		mgl.glMultiTexCoord4x(target, s, t, r, q);
  		checkError();
  	}
  
  	public void glNormal3f (float nx, float ny, float nz) {
  		begin("glNormal3f");
  		arg("nx", nx);
  		arg("ny", ny);
  		arg("nz", nz);
  		end();
  
  		mgl.glNormal3f(nx, ny, nz);
  		checkError();
  	}
  
  	public void glNormal3x (int nx, int ny, int nz) {
  		begin("glNormal3x");
  		arg("nx", nx);
  		arg("ny", ny);
  		arg("nz", nz);
  		end();
  
  		mgl.glNormal3x(nx, ny, nz);
  		checkError();
  	}
  
  	public void glNormalPointer (int type, int stride, Buffer pointer) {
  		begin("glNormalPointer");
  		arg("type", type);
  		arg("stride", stride);
  		arg("pointer", pointer.toString());
  		end();
  		mNormalPointer = new PointerInfo(3, type, stride, pointer);
  
  		mgl.glNormalPointer(type, stride, pointer);
  		checkError();
  	}
  
  	public void glOrthof (float left, float right, float bottom, float top, float near, float far) {
  		begin("glOrthof");
  		arg("left", left);
  		arg("right", right);
  		arg("bottom", bottom);
  		arg("top", top);
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glOrthof(left, right, bottom, top, near, far);
  		checkError();
  	}
  
  	public void glOrthox (int left, int right, int bottom, int top, int near, int far) {
  		begin("glOrthox");
  		arg("left", left);
  		arg("right", right);
  		arg("bottom", bottom);
  		arg("top", top);
  		arg("near", near);
  		arg("far", far);
  		end();
  
  		mgl.glOrthox(left, right, bottom, top, near, far);
  		checkError();
  	}
  
  	public void glPixelStorei (int pname, int param) {
  		begin("glPixelStorei");
  		arg("pname", pname);
  		arg("param", param);
  		end();
  
  		mgl.glPixelStorei(pname, param);
  		checkError();
  	}
  
  	public void glPointSize (float size) {
  		begin("glPointSize");
  		arg("size", size);
  		end();
  
  		mgl.glPointSize(size);
  		checkError();
  	}
  
  	public void glPointSizex (int size) {
  		begin("glPointSizex");
  		arg("size", size);
  		end();
  
  		mgl.glPointSizex(size);
  		checkError();
  	}
  
  	public void glPolygonOffset (float factor, float units) {
  		begin("glPolygonOffset");
  		arg("factor", factor);
  		arg("units", units);
  		end();
  		mgl.glPolygonOffset(factor, units);
  		checkError();
  	}
  
  	public void glPolygonOffsetx (int factor, int units) {
  		begin("glPolygonOffsetx");
  		arg("factor", factor);
  		arg("units", units);
  		end();
  
  		mgl.glPolygonOffsetx(factor, units);
  		checkError();
  	}
  
  	public void glPopMatrix () {
  		begin("glPopMatrix");
  		end();
  
  		mgl.glPopMatrix();
  		checkError();
  	}
  
  	public void glPushMatrix () {
  		begin("glPushMatrix");
  		end();
  
  		mgl.glPushMatrix();
  		checkError();
  	}
  
  	public void glReadPixels (int x, int y, int width, int height, int format, int type, Buffer pixels) {
  		begin("glReadPixels");
  		arg("x", x);
  		arg("y", y);
  		arg("width", width);
  		arg("height", height);
  		arg("format", format);
  		arg("type", type);
  		arg("pixels", pixels.toString());
  		end();
  
  		mgl.glReadPixels(x, y, width, height, format, type, pixels);
  		checkError();
  	}
  
  	public void glRotatef (float angle, float x, float y, float z) {
  		begin("glRotatef");
  		arg("angle", angle);
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  
  		mgl.glRotatef(angle, x, y, z);
  		checkError();
  	}
  
  	public void glRotatex (int angle, int x, int y, int z) {
  		begin("glRotatex");
  		arg("angle", angle);
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  
  		mgl.glRotatex(angle, x, y, z);
  		checkError();
  	}
  
  	public void glSampleCoverage (float value, boolean invert) {
  		begin("glSampleCoveragex");
  		arg("value", value);
  		arg("invert", invert);
  		end();
  
  		mgl.glSampleCoverage(value, invert);
  		checkError();
  	}
  
  	public void glSampleCoveragex (int value, boolean invert) {
  		begin("glSampleCoveragex");
  		arg("value", value);
  		arg("invert", invert);
  		end();
  
  		mgl.glSampleCoveragex(value, invert);
  		checkError();
  	}
  
  	public void glScalef (float x, float y, float z) {
  		begin("glScalef");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  
  		mgl.glScalef(x, y, z);
  		checkError();
  	}
  
  	public void glScalex (int x, int y, int z) {
  		begin("glScalex");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  
  		mgl.glScalex(x, y, z);
  		checkError();
  	}
  
  	public void glScissor (int x, int y, int width, int height) {
  		begin("glScissor");
  		arg("x", x);
  		arg("y", y);
  		arg("width", width);
  		arg("height", height);
  		end();
  
  		mgl.glScissor(x, y, width, height);
  		checkError();
  	}
  
  	public void glShadeModel (int mode) {
  		begin("glShadeModel");
  		arg("mode", getShadeModel(mode));
  		end();
  
  		mgl.glShadeModel(mode);
  		checkError();
  	}
  
  	public void glStencilFunc (int func, int ref, int mask) {
  		begin("glStencilFunc");
  		arg("func", func);
  		arg("ref", ref);
  		arg("mask", mask);
  		end();
  
  		mgl.glStencilFunc(func, ref, mask);
  		checkError();
  	}
  
  	public void glStencilMask (int mask) {
  		begin("glStencilMask");
  		arg("mask", mask);
  		end();
  
  		mgl.glStencilMask(mask);
  		checkError();
  	}
  
  	public void glStencilOp (int fail, int zfail, int zpass) {
  		begin("glStencilOp");
  		arg("fail", fail);
  		arg("zfail", zfail);
  		arg("zpass", zpass);
  		end();
  
  		mgl.glStencilOp(fail, zfail, zpass);
  		checkError();
  	}
  
  	public void glTexCoordPointer (int size, int type, int stride, Buffer pointer) {
  		begin("glTexCoordPointer");
  		argPointer(size, type, stride, pointer);
  		end();
  		mTexCoordPointer = new PointerInfo(size, type, stride, pointer);
  
  		mgl.glTexCoordPointer(size, type, stride, pointer);
  		checkError();
  	}
  
  	public void glTexEnvf (int target, int pname, float param) {
  		begin("glTexEnvf");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("param", getTextureEnvParamName(param));
  		end();
  
  		mgl.glTexEnvf(target, pname, param);
  		checkError();
  	}
  
  	public void glTexEnvfv (int target, int pname, float[] params, int offset) {
  		begin("glTexEnvfv");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("params", getTextureEnvParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glTexEnvfv(target, pname, params, offset);
  		checkError();
  	}
  
  	public void glTexEnvfv (int target, int pname, FloatBuffer params) {
  		begin("glTexEnvfv");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("params", getTextureEnvParamCount(pname), params);
  		end();
  
  		mgl.glTexEnvfv(target, pname, params);
  		checkError();
  	}
  
  	public void glTexEnvx (int target, int pname, int param) {
  		begin("glTexEnvx");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glTexEnvx(target, pname, param);
  		checkError();
  	}
  
  	public void glTexEnvxv (int target, int pname, int[] params, int offset) {
  		begin("glTexEnvxv");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("params", getTextureEnvParamCount(pname), params, offset);
  		arg("offset", offset);
  		end();
  
  		mgl.glTexEnvxv(target, pname, params, offset);
  		checkError();
  	}
  
  	public void glTexEnvxv (int target, int pname, IntBuffer params) {
  		begin("glTexEnvxv");
  		arg("target", getTextureEnvTarget(target));
  		arg("pname", getTextureEnvPName(pname));
  		arg("params", getTextureEnvParamCount(pname), params);
  		end();
  
  		mgl.glTexEnvxv(target, pname, params);
  		checkError();
  	}
  
  	public void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type,
  		Buffer pixels) {
  		begin("glTexImage2D");
  		arg("target", target);
  		arg("level", level);
  		arg("internalformat", internalformat);
  		arg("width", width);
  		arg("height", height);
  		arg("border", border);
  		arg("format", format);
  		arg("type", type);
  		arg("pixels", pixels.toString());
  		end();
  
  		mgl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
  		checkError();
  	}
  
  	public void glTexParameterf (int target, int pname, float param) {
  		begin("glTexParameterf");
  		arg("target", getTextureTarget(target));
  		arg("pname", getTexturePName(pname));
  		arg("param", getTextureParamName(param));
  		end();
  
  		mgl.glTexParameterf(target, pname, param);
  		checkError();
  	}
  
  	public void glTexParameterx (int target, int pname, int param) {
  		begin("glTexParameterx");
  		arg("target", getTextureTarget(target));
  		arg("pname", getTexturePName(pname));
  		arg("param", param);
  		end();
  
  		mgl.glTexParameterx(target, pname, param);
  		checkError();
  	}
  
  	public void glTexParameteriv (int target, int pname, int[] params, int offset) {
  		begin("glTexParameteriv");
  		arg("target", getTextureTarget(target));
  		arg("pname", getTexturePName(pname));
  		arg("params", 4, params, offset);
  		end();
  
  		mgl11.glTexParameteriv(target, pname, params, offset);
  		checkError();
  	}
  
  	public void glTexParameteriv (int target, int pname, IntBuffer params) {
  		begin("glTexParameteriv");
  		arg("target", getTextureTarget(target));
  		arg("pname", getTexturePName(pname));
  		arg("params", 4, params);
  		end();
  
  		mgl11.glTexParameteriv(target, pname, params);
  		checkError();
  	}
  
  	public void glTexSubImage2D (int target, int level, int xoffset, int yoffset, int width, int height, int format, int type,
  		Buffer pixels) {
  		begin("glTexSubImage2D");
  		arg("target", getTextureTarget(target));
  		arg("level", level);
  		arg("xoffset", xoffset);
  		arg("yoffset", yoffset);
  		arg("width", width);
  		arg("height", height);
  		arg("format", format);
  		arg("type", type);
  		arg("pixels", pixels.toString());
  		end();
  		mgl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
  		checkError();
  	}
  
  	public void glTranslatef (float x, float y, float z) {
  		begin("glTranslatef");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  		mgl.glTranslatef(x, y, z);
  		checkError();
  	}
  
  	public void glTranslatex (int x, int y, int z) {
  		begin("glTranslatex");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		end();
  		mgl.glTranslatex(x, y, z);
  		checkError();
  	}
  
  	public void glVertexPointer (int size, int type, int stride, Buffer pointer) {
  		begin("glVertexPointer");
  		argPointer(size, type, stride, pointer);
  		end();
  		mVertexPointer = new PointerInfo(size, type, stride, pointer);
  		mgl.glVertexPointer(size, type, stride, pointer);
  		checkError();
  	}
  
  	public void glViewport (int x, int y, int width, int height) {
  		begin("glViewport");
  		arg("x", x);
  		arg("y", y);
  		arg("width", width);
  		arg("height", height);
  		end();
  		mgl.glViewport(x, y, width, height);
  		checkError();
  	}
  
  	public void glClipPlanef (int plane, float[] equation, int offset) {
  		begin("glClipPlanef");
  		arg("plane", plane);
  		arg("equation", 4, equation, offset);
  		arg("offset", offset);
  		end();
  		mgl11.glClipPlanef(plane, equation, offset);
  		checkError();
  	}
  
  	public void glClipPlanef (int plane, FloatBuffer equation) {
  		begin("glClipPlanef");
  		arg("plane", plane);
  		arg("equation", 4, equation);
  		end();
  		mgl11.glClipPlanef(plane, equation);
  		checkError();
  	}
  
  	public void glClipPlanex (int plane, int[] equation, int offset) {
  		begin("glClipPlanex");
  		arg("plane", plane);
  		arg("equation", 4, equation, offset);
  		arg("offset", offset);
  		end();
  		mgl11.glClipPlanex(plane, equation, offset);
  		checkError();
  	}
  
  	public void glClipPlanex (int plane, IntBuffer equation) {
  		begin("glClipPlanef");
  		arg("plane", plane);
  		arg("equation", 4, equation);
  		end();
  		mgl11.glClipPlanex(plane, equation);
  		checkError();
  	}
  
  	// Draw Texture Extension
  
  	public void glDrawTexfOES (float x, float y, float z, float width, float height) {
  		begin("glDrawTexfOES");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		arg("width", width);
  		arg("height", height);
  		end();
  		mgl11Ext.glDrawTexfOES(x, y, z, width, height);
  		checkError();
  	}
  
  	public void glDrawTexfvOES (float[] coords, int offset) {
  		begin("glDrawTexfvOES");
  		arg("coords", 5, coords, offset);
  		arg("offset", offset);
  		end();
  		mgl11Ext.glDrawTexfvOES(coords, offset);
  		checkError();
  	}
  
  	public void glDrawTexfvOES (FloatBuffer coords) {
  		begin("glDrawTexfvOES");
  		arg("coords", 5, coords);
  		end();
  		mgl11Ext.glDrawTexfvOES(coords);
  		checkError();
  	}
  
  	public void glDrawTexiOES (int x, int y, int z, int width, int height) {
  		begin("glDrawTexiOES");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		arg("width", width);
  		arg("height", height);
  		end();
  		mgl11Ext.glDrawTexiOES(x, y, z, width, height);
  		checkError();
  	}
  
  	public void glDrawTexivOES (int[] coords, int offset) {
  		begin("glDrawTexivOES");
  		arg("coords", 5, coords, offset);
  		arg("offset", offset);
  		end();
  		mgl11Ext.glDrawTexivOES(coords, offset);
  		checkError();
  	}
  
  	public void glDrawTexivOES (IntBuffer coords) {
  		begin("glDrawTexivOES");
  		arg("coords", 5, coords);
  		end();
  		mgl11Ext.glDrawTexivOES(coords);
  		checkError();
  	}
  
  	public void glDrawTexsOES (short x, short y, short z, short width, short height) {
  		begin("glDrawTexsOES");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		arg("width", width);
  		arg("height", height);
  		end();
  		mgl11Ext.glDrawTexsOES(x, y, z, width, height);
  		checkError();
  	}
  
  	public void glDrawTexsvOES (short[] coords, int offset) {
  		begin("glDrawTexsvOES");
  		arg("coords", 5, coords, offset);
  		arg("offset", offset);
  		end();
  		mgl11Ext.glDrawTexsvOES(coords, offset);
  		checkError();
  	}
  
  	public void glDrawTexsvOES (ShortBuffer coords) {
  		begin("glDrawTexsvOES");
  		arg("coords", 5, coords);
  		end();
  		mgl11Ext.glDrawTexsvOES(coords);
  		checkError();
  	}
  
  	public void glDrawTexxOES (int x, int y, int z, int width, int height) {
  		begin("glDrawTexxOES");
  		arg("x", x);
  		arg("y", y);
  		arg("z", z);
  		arg("width", width);
  		arg("height", height);
  		end();
  		mgl11Ext.glDrawTexxOES(x, y, z, width, height);
  		checkError();
  	}
  
  	public void glDrawTexxvOES (int[] coords, int offset) {
  		begin("glDrawTexxvOES");
  		arg("coords", 5, coords, offset);
  		arg("offset", offset);
  		end();
  		mgl11Ext.glDrawTexxvOES(coords, offset);
  		checkError();
  	}
  
  	public void glDrawTexxvOES (IntBuffer coords) {
  		begin("glDrawTexxvOES");
  		arg("coords", 5, coords);
  		end();
  		mgl11Ext.glDrawTexxvOES(coords);
  		checkError();
  	}
  
  	public int glQueryMatrixxOES (int[] mantissa, int mantissaOffset, int[] exponent, int exponentOffset) {
  		begin("glQueryMatrixxOES");
  		arg("mantissa", Arrays.toString(mantissa));
  		arg("exponent", Arrays.toString(exponent));
  		end();
  		int valid = mgl10Ext.glQueryMatrixxOES(mantissa, mantissaOffset, exponent, exponentOffset);
  		returns(toString(16, FORMAT_FIXED, mantissa, mantissaOffset));
  		returns(toString(16, FORMAT_INT, exponent, exponentOffset));
  		checkError();
  		return valid;
  	}
  
  	public int glQueryMatrixxOES (IntBuffer mantissa, IntBuffer exponent) {
  		begin("glQueryMatrixxOES");
  		arg("mantissa", mantissa.toString());
  		arg("exponent", exponent.toString());
  		end();
  		int valid = mgl10Ext.glQueryMatrixxOES(mantissa, exponent);
  		returns(toString(16, FORMAT_FIXED, mantissa));
  		returns(toString(16, FORMAT_INT, exponent));
  		checkError();
  		return valid;
  	}
  
  	// Unsupported GL11 methods
  
  	public void glBindBuffer (int target, int buffer) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glBufferData (int target, int size, Buffer data, int usage) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glBufferSubData (int target, int offset, int size, Buffer data) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glColor4ub (byte red, byte green, byte blue, byte alpha) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glDeleteBuffers (int n, int[] buffers, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glDeleteBuffers (int n, IntBuffer buffers) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGenBuffers (int n, int[] buffers, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGenBuffers (int n, IntBuffer buffers) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetBooleanv (int pname, boolean[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetBooleanv (int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetBufferParameteriv (int target, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetBufferParameteriv (int target, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetClipPlanef (int pname, float[] eqn, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetClipPlanef (int pname, FloatBuffer eqn) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetClipPlanex (int pname, int[] eqn, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetClipPlanex (int pname, IntBuffer eqn) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetFixedv (int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetFixedv (int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetFloatv (int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetFloatv (int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetLightfv (int light, int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetLightfv (int light, int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetLightxv (int light, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetLightxv (int light, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetMaterialfv (int face, int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetMaterialfv (int face, int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetMaterialxv (int face, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetMaterialxv (int face, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexEnviv (int env, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexEnviv (int env, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexEnvxv (int env, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexEnvxv (int env, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameterfv (int target, int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameterfv (int target, int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameteriv (int target, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameteriv (int target, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameterxv (int target, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glGetTexParameterxv (int target, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public boolean glIsBuffer (int buffer) {
  		throw new UnsupportedOperationException();
  	}
  
  	public boolean glIsEnabled (int cap) {
  		throw new UnsupportedOperationException();
  	}
  
  	public boolean glIsTexture (int texture) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterf (int pname, float param) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterfv (int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterfv (int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterx (int pname, int param) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterxv (int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointParameterxv (int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glPointSizePointerOES (int type, int stride, Buffer pointer) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexEnvi (int target, int pname, int param) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexEnviv (int target, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexEnviv (int target, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexParameterfv (int target, int pname, float[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexParameterfv (int target, int pname, FloatBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexParameteri (int target, int pname, int param) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexParameterxv (int target, int pname, int[] params, int offset) {
  		throw new UnsupportedOperationException();
  	}
  
  	public void glTexParameterxv (int target, int pname, IntBuffer params) {
  		throw new UnsupportedOperationException();
  	}
  
  	private class PointerInfo {
  		/**
  		 * The number of coordinates per vertex. 1..4
  		 */
  		public int mSize;
  		/**
  		 * The type of each coordinate.
  		 */
  		public int mType;
  		/**
  		 * The byte offset between consecutive vertices. 0 means mSize * sizeof(mType)
  		 */
  		public int mStride;
  		public Buffer mPointer;
  		public ByteBuffer mTempByteBuffer; // Only valid during glDrawXXX calls
  
  		public PointerInfo (int size, int type, int stride, Buffer pointer) {
  			mSize = size;
  			mType = type;
  			mStride = stride;
  			mPointer = pointer;
  		}
  
  		public int sizeof (int type) {
  			switch (type) {
  			case GL_UNSIGNED_BYTE:
  				return 1;
  			case GL_BYTE:
  				return 1;
  			case GL_SHORT:
  				return 2;
  			case GL_FIXED:
  				return 4;
  			case GL_FLOAT:
  				return 4;
  			default:
  				return 0;
  			}
  		}
  
  		public int getStride () {
  			return mStride > 0 ? mStride : sizeof(mType) * mSize;
  		}
  
  		public void bindByteBuffer () {
  			mTempByteBuffer = toByteBuffer(-1, mPointer);
  		}
  
  		public void unbindByteBuffer () {
  			mTempByteBuffer = null;
  		}
  	}
  
  	private Writer mLog;
  	private boolean mLogArgumentNames;
  	private int mArgCount;
  
  	private PointerInfo mColorPointer;
  	private PointerInfo mNormalPointer;
  	private PointerInfo mTexCoordPointer;
  	private PointerInfo mVertexPointer;
  
  	boolean mColorArrayEnabled;
  	boolean mNormalArrayEnabled;
  	boolean mTextureCoordArrayEnabled;
  	boolean mVertexArrayEnabled;
  
  	StringBuilder mStringBuilder;
  }
  