00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.android.view.visualization;
00018
00019 import com.google.common.base.Preconditions;
00020
00021 import android.graphics.Bitmap;
00022 import android.opengl.GLUtils;
00023 import org.jboss.netty.buffer.ChannelBuffer;
00024 import org.ros.rosjava_geometry.Transform;
00025
00026 import java.nio.FloatBuffer;
00027
00028 import javax.microedition.khronos.opengles.GL10;
00029
00036 public class TextureBitmap implements OpenGlDrawable {
00037
00041 private final static int TEXTURE_HEIGHT = 1024;
00042
00046 private final static int TEXTURE_STRIDE = 1024;
00047
00048 private final int[] pixels;
00049 private final FloatBuffer surfaceVertices;
00050 private final FloatBuffer textureVertices;
00051 private final Object mutex;
00052
00053 private Bitmap bitmapFront;
00054 private Bitmap bitmapBack;
00055 private int[] handle;
00056 private Transform origin;
00057 private double scaledWidth;
00058 private double scaledHeight;
00059 private boolean reload;
00060
00061 public TextureBitmap() {
00062 pixels = new int[TEXTURE_HEIGHT * TEXTURE_STRIDE];
00063 surfaceVertices = Vertices.toFloatBuffer(new float[] {
00064
00065 0.0f, 0.0f, 0.0f,
00066 1.0f, 0.0f, 0.0f,
00067 0.0f, 1.0f, 0.0f,
00068 1.0f, 1.0f, 0.0f,
00069 });
00070 textureVertices = Vertices.toFloatBuffer(new float[] {
00071
00072 0.0f, 0.0f,
00073 1.0f, 0.0f,
00074 0.0f, 1.0f,
00075 1.0f, 1.0f,
00076 });
00077 bitmapFront = Bitmap.createBitmap(TEXTURE_STRIDE, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
00078 bitmapBack = Bitmap.createBitmap(TEXTURE_STRIDE, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
00079 mutex = new Object();
00080 reload = true;
00081 }
00082
00083 public void updateFromPixelArray(int[] pixels, int stride, float resolution, Transform origin,
00084 int fillColor) {
00085 Preconditions.checkArgument(pixels.length % stride == 0);
00086 int height = pixels.length / stride;
00087 for (int y = 0; y < TEXTURE_HEIGHT; y++) {
00088 for (int x = 0; x < TEXTURE_STRIDE; x++) {
00089
00090
00091
00092 int sourceIndex = y * stride + x;
00093 int targetIndex = y * TEXTURE_STRIDE + x;
00094 if (x < stride && y < height) {
00095 this.pixels[targetIndex] = pixels[sourceIndex];
00096 } else {
00097 this.pixels[targetIndex] = fillColor;
00098 }
00099 }
00100 }
00101 update(origin, stride, resolution, fillColor);
00102 }
00103
00104 public void updateFromPixelBuffer(ChannelBuffer pixels, int stride, float resolution,
00105 Transform origin, int fillColor) {
00106 Preconditions.checkNotNull(pixels);
00107 Preconditions.checkNotNull(origin);
00108 for (int y = 0, i = 0; y < TEXTURE_HEIGHT; y++) {
00109 for (int x = 0; x < TEXTURE_STRIDE; x++, i++) {
00110
00111
00112
00113 if (x < stride && pixels.readable()) {
00114 this.pixels[i] = pixels.readInt();
00115 } else {
00116 this.pixels[i] = fillColor;
00117 }
00118 }
00119 }
00120 update(origin, stride, resolution, fillColor);
00121 }
00122
00123 public void clearHandle() {
00124 handle = null;
00125 }
00126
00127 private void update(Transform origin, int stride, float resolution, int fillColor) {
00128 this.origin = origin;
00129 scaledWidth = TEXTURE_STRIDE * resolution;
00130 scaledHeight = TEXTURE_HEIGHT * resolution;
00131 bitmapBack.setPixels(pixels, 0, TEXTURE_STRIDE, 0, 0, TEXTURE_STRIDE, TEXTURE_HEIGHT);
00132 synchronized (mutex) {
00133 Bitmap tmp = bitmapFront;
00134 bitmapFront = bitmapBack;
00135 bitmapBack = tmp;
00136 reload = true;
00137 }
00138 }
00139
00140 private void bind(GL10 gl) {
00141 if (handle == null) {
00142 handle = new int[1];
00143 gl.glGenTextures(1, handle, 0);
00144 gl.glBindTexture(GL10.GL_TEXTURE_2D, handle[0]);
00145 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
00146 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
00147 reload = true;
00148 }
00149 synchronized (mutex) {
00150 if (reload) {
00151 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapFront, 0);
00152 reload = false;
00153 }
00154 }
00155 }
00156
00157 @Override
00158 public void draw(GL10 gl) {
00159 gl.glEnable(GL10.GL_TEXTURE_2D);
00160 bind(gl);
00161 gl.glPushMatrix();
00162 OpenGlTransform.apply(gl, origin);
00163 gl.glScalef((float) scaledWidth, (float) scaledHeight, 1.0f);
00164 gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00165 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
00166 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
00167 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, surfaceVertices);
00168 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureVertices);
00169 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
00170 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
00171 gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
00172 gl.glPopMatrix();
00173 gl.glDisable(GL10.GL_TEXTURE_2D);
00174 }
00175 }