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