diff --git a/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java b/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java index 2cb182e27f76a2c62cd437cbf49a912af730db39..8868ab9f65fe147e603eb8f1fd5e7fcd6277a849 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java @@ -19,14 +19,23 @@ public class GLESRender implements Renderer{ mGModel.load(filename); } - public void translate(float tx, float ty, float tz){ - mGModel.translation(tx, ty, tz); + public void startInteraction(float x, float y) { + mGModel.startEvent(x, y); } - public void scale(float sx, float sy, float sz){ - mGModel.scale(sx, sy, sz); + public void endInteraction(float x, float y) { + mGModel.endEvent(x, y); } - public void rotate(float rx, float ry, float rz){ - mGModel.rotate(rx, ry, rz); + public void rotateModel(float x, float y) { + mGModel.rotate(x, y); + } + public void scaleModel(float s) { + mGModel.scale(s); + } + public void translateModel(float x, float y) { + mGModel.translate(x, y); + } + public void resetModelPosition() { + mGModel.resetPosition(); } // OpenGL ES methods diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java index f13d71f968f7f75bff5f72c2711cdba21813b023..baff69f3f97bc6e9111612a16c7fff38be1f2d7b 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java @@ -17,9 +17,7 @@ public class Gmsh { private native void loadFile(long ptr, String name); // load a file(OpenProjet) private native void initView(long ptr, int w, int h); // Called each time the GLView change private native void drawView(long ptr); // Called each time the GLView request a render - private native void setTranslation(long ptr, float tx, float ty, float tz); // translate the current GModel - private native void setScale(long ptr, float sx, float sy, float sz); // scale the current GModel - private native void setRotate(long ptr, float rx, float ry, float rz); // rotate the current GModel + private native void eventHandler(long ptr, int event, float x, float y); private native void setShow(long ptr, String what, boolean show); // select what to show / hide private native long getOnelabInstance(); // return the singleton of the onelab server public native String[] getParams(); // return the parameters for onelab @@ -51,18 +49,29 @@ public class Gmsh { this.loadFile(ptr, filename); } - public void translation(float tx, float ty, float tz) + public void startEvent(float x, float y) { - this.setTranslation(ptr, tx, ty, tz); + this.eventHandler(ptr, 0, x, y); } - - public void scale(float sx, float sy, float sz) + public void translate(float x, float y) { - this.setScale(ptr, sx, sy, sz); + this.eventHandler(ptr, 1, x, y); } - - public void rotate(float rx, float ry, float rz) { - this.setRotate(ptr, rx, ry, rz); + public void scale(float s) + { + this.eventHandler(ptr, 2, s, 0); + } + public void rotate(float x, float y) + { + this.eventHandler(ptr, 3, x, y); + } + public void endEvent(float x, float y) + { + this.eventHandler(ptr, 4, x, y); + } + public void resetPosition() + { + this.eventHandler(ptr, 5, 0, 0); } public void showGeom(boolean show) { diff --git a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java index 7153b3a390955c6622aa3ffcad05b088b1c80d0b..40156b8e49d3846e89119c4e9fd4d4c390f4b594 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java @@ -102,6 +102,12 @@ public class MainActivity extends Activity { setContentView(layout); } + @Override + protected void onDestroy() { + // TODO Unload library ? + super.onDestroy(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); @@ -134,8 +140,12 @@ public class MainActivity extends Activity { public boolean onMenuItemSelected(int featureId, MenuItem item) { if(item.getTitle().equals(getString(R.string.menu_settings))) pager.setCurrentItem(0, true); - else if(item.getTitle().equals(getString(R.string.menu_list))) - this.finish(); + else if(item.getTitle().equals(getString(R.string.menu_list))) { + if(this.compute) + loading.show(); + else + this.finish(); + } else if (item.getTitle().equals(getString(R.string.menu_model))) pager.setCurrentItem(1, true); else if(item.getTitle().equals(getString(R.string.menu_postpro))){ @@ -144,7 +154,7 @@ public class MainActivity extends Activity { .setPositiveButton("Ok", null) .show(); } - else if(item.getTitle().equals(getString(R.string.menu_view_x))){ + /*else if(item.getTitle().equals(getString(R.string.menu_view_x))){ renderer.rotate(0, 0, 0); renderer.rotate(90, 0, 0); glView.requestRender(); @@ -165,7 +175,7 @@ public class MainActivity extends Activity { else if(item.getTitle().equals(getString(R.string.menu_view_translation))){ renderer.translate(0, 0, 0); glView.requestRender(); - } + }*/ // TODO return super.onMenuItemSelected(featureId, item); } @@ -499,11 +509,11 @@ public class MainActivity extends Activity { @Override protected void onPostExecute(Integer[] result) { Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - v.vibrate(350); + if(!v.hasVibrator()) // TODO Do not commit this line ! + v.vibrate(350); reset.setEnabled(true); run.setEnabled(true); //run.setText("Run"); // TODO this seems break the ViewPager - pager.postInvalidate(); glView.requestRender(); super.onPostExecute(result); loading.dismiss(); diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java index 45743cf12586ee378e7f51876bc58ee3f7b265a4..9b8e937fad6808a9db9f1b5602637962cf0e687b 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java @@ -107,11 +107,11 @@ public class ParameterString extends Parameter{ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { - if(_listView != null) _listView.refresh(); setValue(pos); _gmsh.setParam(getType(), getName(), String.valueOf(getValue())); if(_gmsh.onelabCB("check") == 1 && _glView != null) _glView.requestRender(); + if(_listView != null) _listView.refresh(); } }); diff --git a/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java b/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java new file mode 100644 index 0000000000000000000000000000000000000000..3faa40d28370dc246e11841bd6677610847386d0 --- /dev/null +++ b/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java @@ -0,0 +1,172 @@ +package org.geuz.onelab; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.opengles.GL10; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Bitmap.CompressFormat; +import android.opengl.GLUtils; +import android.os.Environment; + +public class StringTexture { + private String _text; + private Bitmap _bitmap; + private int[] _textures = new int[1]; // Texture pointer + + public StringTexture(String s) { + _text = s; + getBitmapFromText(12.0f, Color.BLACK); + } + + private void getBitmapFromText(float textSize, int textColor) { + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setColor(textColor); + paint.setTextAlign(Paint.Align.LEFT); + int width = (int) (paint.measureText(_text) + 2.5f); // round + int baseline = (int) (textSize + 2.5f); + int height = (int) (baseline + paint.descent() + 2.5f); + _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + _bitmap.eraseColor(Color.TRANSPARENT); + Canvas canvas = new Canvas(_bitmap); + canvas.setBitmap(_bitmap); + canvas.drawText(_text, 0, baseline, paint); + } + + private void loadGLTexture(GL10 gl) { + if(_bitmap == null) return; + gl.glGenTextures(1, _textures, 0); + + gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]); + + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); + gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); + + GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, _bitmap, 0); + + _bitmap.recycle(); + } + + public void draw(GL10 gl, int x, int y) { + gl.glEnable(GL10.GL_TEXTURE_2D); + // VERTEX + float vertex[] = { + -1.0f, -1.0f, 0.0f, // bottom left + -1.0f, 1.0f, 0.0f, // top left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + }; + FloatBuffer vertexBuffer; + ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertex.length * 4); + vertexByteBuffer.order(ByteOrder.nativeOrder()); + vertexBuffer = vertexByteBuffer.asFloatBuffer(); + vertexBuffer.put(vertex); + vertexBuffer.position(0); + + // TEXTURE + FloatBuffer textureBuffer; // buffer holding the texture coordinates + float texture[] = { + 0.0f, 1.0f, // top left + 0.0f, 0.0f, // bottom left + 1.0f, 1.0f, // top right + 1.0f, 0.0f // bottom right + }; + ByteBuffer textureByteBuffer = ByteBuffer.allocateDirect(texture.length * 4); + textureByteBuffer.order(ByteOrder.nativeOrder()); + textureBuffer = textureByteBuffer.asFloatBuffer(); + textureBuffer.put(texture); + textureBuffer.position(0); + loadGLTexture(gl); + gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]); + + + // DRAW + gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); + gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); + gl.glColor4f(1,1,1,1); + gl.glEnable(GL10.GL_BLEND); + gl.glBlendFunc(GL10.GL_SRC_COLOR, GL10.GL_ONE_MINUS_SRC_ALPHA); + gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); + gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); + gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertex.length / 3); + gl.glDisable(GL10.GL_BLEND); + gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); + gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); + gl.glDisable(GL10.GL_TEXTURE_2D); + } + + public static byte[] getBytesFromString(String s, int textSize) + { + // Generate the bitmap + int textColor = Color.BLACK; + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setColor(textColor); + paint.setTextAlign(Paint.Align.LEFT); + int width = (int) (paint.measureText(s) + 0.5f); // round + int i; + for(i=2;i<=width;i*=2); width = i; + int baseline = (int) (textSize + 0.5f); + int height = (int) (baseline + paint.descent() + 0.5f); + for(i=2;i<=height;i*=2); height = i; + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + bitmap.eraseColor(Color.WHITE); + Canvas canvas = new Canvas(bitmap); + canvas.setBitmap(bitmap); + canvas.drawText(s, 0, baseline, paint); + // TMP + try { + FileOutputStream stream = new FileOutputStream(Environment.getExternalStorageDirectory()+"/test.jpg"); + bitmap.compress(CompressFormat.JPEG, 80, stream); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // Get the pixel in a map + ByteBuffer buffer = ByteBuffer.allocateDirect(width*height); + buffer.order(ByteOrder.nativeOrder()); + buffer.position(0); + for(int y = 0; y<height;y++) + for(int x = 0; x<width;x++) + buffer.put((byte) ((bitmap.getPixel(x, y) == Color.BLACK)? 0xFF : 0x00)); + buffer.position(0); + byte[] b = new byte[buffer.capacity()]; + buffer.get(b); + return b; + } + public static int getWidthFromString(String s, int textSize) + { + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setTextAlign(Paint.Align.LEFT); + int ret = (int) (paint.measureText(s) + 0.5f); + int i; + for(i=2;i<=ret;i*=2); ret = i; + return ret; + } + public static int getRealWidthFromString(String s, int textSize) + { + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setTextAlign(Paint.Align.LEFT); + return (int) (paint.measureText(s) + 0.5f); + } + public static int getHeightFromString(String s, int textSize) + { + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setTextAlign(Paint.Align.LEFT); + int ret = (int) (textSize + 0.5f + paint.descent() + 0.5f); + int i; + for(i=2;i<=ret;i*=2); ret = i; + return ret; + } +} diff --git a/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java b/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java index d57d57dfc68c6649d35f11e827101f6bf218d39d..2910b6e3387621e60be52c5254786252a3d8c1da 100644 --- a/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java +++ b/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java @@ -6,7 +6,6 @@ import android.support.v4.view.MotionEventCompat; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; -import android.view.View; import android.view.GestureDetector.OnDoubleTapListener; import android.view.GestureDetector.OnGestureListener; import android.view.ScaleGestureDetector.OnScaleGestureListener; @@ -15,22 +14,26 @@ class mGLSurfaceView extends GLSurfaceView { private float scaleFactor = 1f; private GestureDetector gesture; private ScaleGestureDetector scaleGesture; - private float lastX, lastY; private GLESRender _renderer; public mGLSurfaceView(Context context, GLESRender renderer) { super(context); _renderer = renderer; - gesture = new GestureDetector(context, new GestureListener(this)); + gesture = new GestureDetector(context, new GestureListener()); scaleGesture = new ScaleGestureDetector(context, new OnScaleGestureListener() { - public void onScaleEnd(ScaleGestureDetector detector) {}// UNUSED Auto-generated method stub + public void onScaleEnd(ScaleGestureDetector detector) { + _renderer.endInteraction(detector.getFocusX(), detector.getFocusY()); + } - public boolean onScaleBegin(ScaleGestureDetector detector) {return true;}// UNUSED Auto-generated method stub + public boolean onScaleBegin(ScaleGestureDetector detector) { + _renderer.startInteraction(detector.getFocusX(), detector.getFocusY()); + return true; + } public boolean onScale(ScaleGestureDetector detector) { scaleFactor *= detector.getScaleFactor(); - scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 50.0f)); - _renderer.scale(scaleFactor, scaleFactor, scaleFactor); + scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 50.0f)); // limit the scale factor + _renderer.scaleModel(scaleFactor); requestRender(); return true; @@ -49,17 +52,14 @@ class mGLSurfaceView extends GLSurfaceView { int action = MotionEventCompat.getActionMasked(event); if(action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_1_DOWN){ - lastX = x; - lastY = y; + _renderer.startInteraction(x,y); } else if(action == MotionEvent.ACTION_MOVE){ - float dx = x - lastX, - dy = y - lastY; - if(dx != 0 || dy != 0) - _renderer.rotate(dy, dx, 0); + _renderer.rotateModel(x, y); requestRender(); - lastX = x; - lastY = y; + } + else if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_1_UP){ + _renderer.endInteraction(x, y); } return true; @@ -72,12 +72,8 @@ class mGLSurfaceView extends GLSurfaceView { } private class GestureListener implements OnGestureListener, OnDoubleTapListener{ - //private View view; - public GestureListener(View view) { - //this.view = view; - } public boolean onDown(MotionEvent e) { - // UNUSED Auto-generated method stub + _renderer.startInteraction(e.getX(),e.getY()); return true; } @@ -94,7 +90,7 @@ class mGLSurfaceView extends GLSurfaceView { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - _renderer.translate(-distanceX, distanceY, 0f); + _renderer.translateModel(e2.getX(), e2.getY()); requestRender(); return false; } @@ -113,10 +109,8 @@ class mGLSurfaceView extends GLSurfaceView { return false; } public boolean onDoubleTapEvent(MotionEvent e) { - _renderer.translate(0f, 0f, 0f); scaleFactor = 1f; - _renderer.scale(scaleFactor, scaleFactor, scaleFactor); - _renderer.rotate(0, 0, 0); + _renderer.resetModelPosition(); requestRender(); return false; } @@ -128,6 +122,6 @@ class mGLSurfaceView extends GLSurfaceView { } public void resetScale(){ scaleFactor = 1f; - _renderer.scale(scaleFactor, scaleFactor, scaleFactor); + _renderer.scaleModel(scaleFactor); } } diff --git a/contrib/mobile/androidGModel.cpp b/contrib/mobile/androidGModel.cpp index 0827a1aa07362e434fe6a8f996cea965022bcce5..17ecf573e5ec0332b446ddc4ecab59b2f1d990d3 100644 --- a/contrib/mobile/androidGModel.cpp +++ b/contrib/mobile/androidGModel.cpp @@ -17,10 +17,12 @@ #include "drawContext.h" onelab::server *getOnelab() {return onelab::server::instance();} - +extern "C" +{ static JavaVM *gJavaVM; static JNIEnv *env; static jobject gCallbackObject = NULL; +}; class MobileMessage : public GmshMessage { @@ -94,6 +96,29 @@ void requestRender() env->DeleteLocalRef(jClass); } +void getBitmapFromString(const char *text, int textsize, unsigned char **map, int *height, int *width, int *realWidth) +{ + if(!gCallbackObject || (gJavaVM->AttachCurrentThread(&env, NULL)) < 0) return; + jclass jClass = env->FindClass("org/geuz/onelab/StringTexture"); + if(jClass == 0) + return; + jstring jtext = env->NewStringUTF(text); + jmethodID mid = env->GetStaticMethodID(jClass, "getHeightFromString", "(Ljava/lang/String;I)I"); + *height = env->CallIntMethod(gCallbackObject, mid, jtext, textsize); + mid = env->GetStaticMethodID(jClass, "getWidthFromString", "(Ljava/lang/String;I)I"); + *width = env->CallIntMethod(gCallbackObject, mid, jtext, textsize); + if(realWidth != NULL){ + mid = env->GetStaticMethodID(jClass, "getRealWidthFromString", "(Ljava/lang/String;I)I"); + *realWidth = env->CallIntMethod(gCallbackObject, mid, jtext, textsize); + } + mid = env->GetStaticMethodID(jClass, "getBytesFromString", "(Ljava/lang/String;I)[B"); + jobject jbuffer = env->CallObjectMethod(gCallbackObject, mid, jtext, textsize); + jbyteArray *jarray = reinterpret_cast<jbyteArray*>(&jbuffer); + *map = (unsigned char *) malloc((*height)*(*width)); + env->GetByteArrayRegion(*jarray, 0, (*height)*(*width), (jbyte*)*map); + env->DeleteLocalRef(jClass); +} + extern "C" { JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { gJavaVM = vm; diff --git a/contrib/mobile/androidGModel.h b/contrib/mobile/androidGModel.h index 21192e45a3d46be22d3a1840ac3eea15587c5ac5..9ae8acdf33eeda61f4794b196cd17ad01979845e 100644 --- a/contrib/mobile/androidGModel.h +++ b/contrib/mobile/androidGModel.h @@ -5,7 +5,7 @@ #ifndef _Included_org_geuz_onelab_Gmsh #define _Included_org_geuz_onelab_Gmsh void requestRender(); -unsigned char *getBitmapFromString(const char *text); +void getBitmapFromString(const char *text, int textsize, unsigned char **map, int *height, int *width, int *realWidth=NULL); #ifdef __cplusplus extern "C" { #endif diff --git a/contrib/mobile/drawContext.cpp b/contrib/mobile/drawContext.cpp index fa5875efae988ffbb83be123a7666d8b238b79fc..49fbffd94f57c3af22b05d4e16b7721c10cd0654 100644 --- a/contrib/mobile/drawContext.cpp +++ b/contrib/mobile/drawContext.cpp @@ -34,6 +34,7 @@ #include <gmsh/onelabUtils.h> #include <gmsh/PView.h> #include <gmsh/PViewOptions.h> +#include <gmsh/PViewData.h> #include <gmsh/Context.h> #include <gmsh/StringUtils.h> @@ -43,6 +44,7 @@ #endif #include "drawContext.h" +#include "drawString.h" #include "Trackball.h" static bool locked = false; @@ -340,101 +342,115 @@ void drawContext::drawScale() glPushMatrix(); glLoadIdentity(); // Draw the scale bar - if(PView::list.size() < 1) return; - PView *p = PView::list[PView::list.size()-1]; - PViewOptions *opt = p->getOptions(); + int nPview = 0; + for(int i=0; i<PView::list.size();i++){ + PView *p = PView::list[i]; + PViewOptions *opt = p->getOptions(); + if(!opt->visible) continue; - double width = 6*(this->_right -this->_left) / 10.; - double height = (this->_top - this->_bottom) / 20.; - double box = width / (opt->nbIso ? opt->nbIso : 1); - double xmin = this->_left + (this->_right - this->_left -width)/2.; - double ymin = this->_bottom + height; + double width = 6*(this->_right -this->_left) / 10.; + double height = (this->_top - this->_bottom) / 20.; + double box = width / (opt->nbIso ? opt->nbIso : 1); + double xmin = this->_left + (this->_right - this->_left -width)/2.; + double ymin = this->_bottom + height + 2*height*nPview; - GLfloat *vertex = (GLfloat *)malloc(opt->nbIso*3*4*sizeof(GLfloat)); - GLubyte *color = (GLubyte *)malloc(opt->nbIso*4*4*sizeof(GLubyte)); - for(int i = 0; i < opt->nbIso; i++){ - if(opt->intervalsType == PViewOptions::Discrete || opt->intervalsType == PViewOptions::Numeric) - { - unsigned int col = opt->getColor(i, opt->nbIso); - color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col); - color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col); - color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col); - color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col); - vertex[i*3*4+0] = xmin + i * box; - vertex[i*3*4+1] = ymin; - vertex[i*3*4+2] = 0.; - vertex[i*3*4+3] = xmin + i * box; - vertex[i*3*4+4] = ymin + height; - vertex[i*3*4+5] = 0.; - vertex[i*3*4+6] = xmin + (i + 1) * box; - vertex[i*3*4+7] = ymin; - vertex[i*3*4+8] = 0.; - vertex[i*3*4+9] = xmin + (i + 1) * box; - vertex[i*3*4+10] = ymin + height; - vertex[i*3*4+11] = 0.; - } - else if(opt->intervalsType == PViewOptions::Continuous) - { - double dv = (opt->tmpMax - opt->tmpMin) / (opt->nbIso ? opt->nbIso : 1); - double v1 = opt->tmpMin + i * dv; - unsigned int col1 = opt->getColor(v1, opt->tmpMin, opt->tmpMax, true); - color[i*4*4+0] = color[i*4*4+4] = (GLubyte)CTX::instance()->unpackRed(col1); - color[i*4*4+1] = color[i*4*4+5] = (GLubyte)CTX::instance()->unpackGreen(col1); - color[i*4*4+2] = color[i*4*4+6] = (GLubyte)CTX::instance()->unpackBlue(col1); - color[i*4*4+3] = color[i*4*4+7] = (GLubyte)CTX::instance()->unpackAlpha(col1); - vertex[i*3*4+0] = xmin + i * box; - vertex[i*3*4+1] = ymin; - vertex[i*3*4+2] = 0.; - vertex[i*3*4+3] = xmin + i * box; - vertex[i*3*4+4] = ymin + height; - vertex[i*3*4+5] = 0.; - double v2 = opt->tmpMin + (i + 1) * dv; - unsigned int col2 = opt->getColor(v2, opt->tmpMin, opt->tmpMax, true); - color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col2); - color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col2); - color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col2); - color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col2); - vertex[i*3*4+6] = xmin + (i + 1) * box; - vertex[i*3*4+7] = ymin; - vertex[i*3*4+8] = 0.; - vertex[i*3*4+9] = xmin + (i + 1) * box; - vertex[i*3*4+10] = ymin + height; - vertex[i*3*4+11] = 0.; + GLfloat *vertex = (GLfloat *)malloc(opt->nbIso*3*4*sizeof(GLfloat)); + GLubyte *color = (GLubyte *)malloc(opt->nbIso*4*4*sizeof(GLubyte)); + for(int i = 0; i < opt->nbIso; i++){ + if(opt->intervalsType == PViewOptions::Discrete || opt->intervalsType == PViewOptions::Numeric) + { + unsigned int col = opt->getColor(i, opt->nbIso); + color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col); + color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col); + color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col); + color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col); + vertex[i*3*4+0] = xmin + i * box; + vertex[i*3*4+1] = ymin; + vertex[i*3*4+2] = 0.; + vertex[i*3*4+3] = xmin + i * box; + vertex[i*3*4+4] = ymin + height; + vertex[i*3*4+5] = 0.; + vertex[i*3*4+6] = xmin + (i + 1) * box; + vertex[i*3*4+7] = ymin; + vertex[i*3*4+8] = 0.; + vertex[i*3*4+9] = xmin + (i + 1) * box; + vertex[i*3*4+10] = ymin + height; + vertex[i*3*4+11] = 0.; + } + else if(opt->intervalsType == PViewOptions::Continuous) + { + double dv = (opt->tmpMax - opt->tmpMin) / (opt->nbIso ? opt->nbIso : 1); + double v1 = opt->tmpMin + i * dv; + unsigned int col1 = opt->getColor(v1, opt->tmpMin, opt->tmpMax, true); + color[i*4*4+0] = color[i*4*4+4] = (GLubyte)CTX::instance()->unpackRed(col1); + color[i*4*4+1] = color[i*4*4+5] = (GLubyte)CTX::instance()->unpackGreen(col1); + color[i*4*4+2] = color[i*4*4+6] = (GLubyte)CTX::instance()->unpackBlue(col1); + color[i*4*4+3] = color[i*4*4+7] = (GLubyte)CTX::instance()->unpackAlpha(col1); + vertex[i*3*4+0] = xmin + i * box; + vertex[i*3*4+1] = ymin; + vertex[i*3*4+2] = 0.; + vertex[i*3*4+3] = xmin + i * box; + vertex[i*3*4+4] = ymin + height; + vertex[i*3*4+5] = 0.; + double v2 = opt->tmpMin + (i + 1) * dv; + unsigned int col2 = opt->getColor(v2, opt->tmpMin, opt->tmpMax, true); + color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col2); + color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col2); + color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col2); + color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col2); + vertex[i*3*4+6] = xmin + (i + 1) * box; + vertex[i*3*4+7] = ymin; + vertex[i*3*4+8] = 0.; + vertex[i*3*4+9] = xmin + (i + 1) * box; + vertex[i*3*4+10] = ymin + height; + vertex[i*3*4+11] = 0.; + } + else + { + unsigned int col = opt->getColor(i, opt->nbIso); + color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col); + color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col); + color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col); + color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col); + vertex[i*3*4+0] = xmin + i * box; + vertex[i*3*4+1] = ymin; + vertex[i*3*4+2] = 0.; + vertex[i*3*4+3] = xmin + i * box; + vertex[i*3*4+4] = ymin + height; + vertex[i*3*4+5] = 0.; + vertex[i*3*4+6] = xmin + (i + 1) * box; + vertex[i*3*4+7] = ymin; + vertex[i*3*4+8] = 0.; + vertex[i*3*4+9] = xmin + (i + 1) * box; + vertex[i*3*4+10] = ymin + height; + vertex[i*3*4+11] = 0.; + } } + + glVertexPointer(3, GL_FLOAT, 0, vertex); + glEnableClientState(GL_VERTEX_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, color); + glEnableClientState(GL_COLOR_ARRAY); + if(opt->intervalsType == PViewOptions::Discrete || opt->intervalsType == PViewOptions::Numeric || opt->intervalsType == PViewOptions::Continuous) + glDrawArrays(GL_TRIANGLE_STRIP, 0, opt->nbIso*4); else - { - unsigned int col = opt->getColor(i, opt->nbIso); - color[i*4*4+0] = color[i*4*4+4] = color[i*4*4+8] = color[i*4*4+12] = (GLubyte)CTX::instance()->unpackRed(col); - color[i*4*4+1] = color[i*4*4+5] = color[i*4*4+9] = color[i*4*4+13] = (GLubyte)CTX::instance()->unpackGreen(col); - color[i*4*4+2] = color[i*4*4+6] = color[i*4*4+10] = color[i*4*4+14] = (GLubyte)CTX::instance()->unpackBlue(col); - color[i*4*4+3] = color[i*4*4+7] = color[i*4*4+11] = color[i*4*4+15] = (GLubyte)CTX::instance()->unpackAlpha(col); - vertex[i*3*4+0] = xmin + i * box; - vertex[i*3*4+1] = ymin; - vertex[i*3*4+2] = 0.; - vertex[i*3*4+3] = xmin + i * box; - vertex[i*3*4+4] = ymin + height; - vertex[i*3*4+5] = 0.; - vertex[i*3*4+6] = xmin + (i + 1) * box; - vertex[i*3*4+7] = ymin; - vertex[i*3*4+8] = 0.; - vertex[i*3*4+9] = xmin + (i + 1) * box; - vertex[i*3*4+10] = ymin + height; - vertex[i*3*4+11] = 0.; + glDrawArrays(GL_LINES, 0, opt->nbIso*4); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + free(vertex); + free(color); + char label[1024]; + drawString *lbl = new drawString(p->getData()->getName().c_str(), 16); + lbl->draw(xmin+width/2, ymin-height/2, 0., _width/(_right-_left), _height/(_top-_bottom)); + drawString *val = new drawString(p->getData()->getName().c_str(), 14); + for(int i = 0; i < 3; i++) { + double v = opt->getScaleValue(i, 3, opt->tmpMin, opt->tmpMax); + sprintf(label, opt->format.c_str(), v); + val->setText(label); + val->draw(xmin+i*width/2, ymin+height/2, 0., _width/(_right-_left), _height/(_top-_bottom)); } + nPview++; } - - glVertexPointer(3, GL_FLOAT, 0, vertex); - glEnableClientState(GL_VERTEX_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, color); - glEnableClientState(GL_COLOR_ARRAY); - if(opt->intervalsType == PViewOptions::Discrete || opt->intervalsType == PViewOptions::Numeric || opt->intervalsType == PViewOptions::Continuous) - glDrawArrays(GL_TRIANGLE_STRIP, 0, opt->nbIso*4); - else - glDrawArrays(GL_LINES, 0, opt->nbIso*4); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - free(vertex); - free(color); glPopMatrix(); } @@ -491,7 +507,7 @@ void drawContext::drawGeom() glLineWidth(1); } -void drawContext::drawAxes(double x0, double y0, double z0, double h) +void drawContext::drawAxes(float x0, float y0, float z0, float h) { glLineWidth(1.); glPushMatrix(); @@ -500,7 +516,7 @@ void drawContext::drawAxes(double x0, double y0, double z0, double h) glMultMatrixf(_rotatef); glTranslatef(-x0, -y0, -z0); - const GLfloat axes[] = { + const GLfloat axes[] = { (GLfloat)x0, (GLfloat)y0, (GLfloat)z0, (GLfloat)(x0+h), (GLfloat)y0, (GLfloat)z0, (GLfloat)x0, (GLfloat)y0, (GLfloat)z0, @@ -508,21 +524,27 @@ void drawContext::drawAxes(double x0, double y0, double z0, double h) (GLfloat)x0, (GLfloat)y0, (GLfloat)z0, (GLfloat)x0, (GLfloat)y0, (GLfloat)(z0+h), }; - const GLubyte colors[] = { - 255, 0, 0, 255, - 255, 0, 0, 255, - 0, 0, 255, 255, - 0, 0, 255, 255, - 0, 255, 0, 255, - 0, 255, 0, 255, - }; + GLfloat colors[] = { + 1., 0, 0, 1., + 1., 0, 0, 1., + 0, 0, 1., 1., + 0, 0, 1., 1., + 0, 1., 0, 1., + 0, 1., 0, 1., + }; glVertexPointer(3, GL_FLOAT, 0, axes); glEnableClientState(GL_VERTEX_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); - glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, 0, colors); + glEnableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_LINES, 0, 6); glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + drawString *x = new drawString("X", 16,colors); + x->draw(x0+h, y0, z0, _width/(_right-_left), _height/(_top-_bottom)); + drawString *y = new drawString("Y", 16,colors+8); + y->draw(x0, y0+h, z0, _width/(_right-_left), _height/(_top-_bottom)); + drawString *z = new drawString("Z", 16,colors+16); + z->draw(x0, y0, z0+h, _width/(_right-_left), _height/(_top-_bottom)); glPopMatrix(); glLineWidth(1); } @@ -577,7 +599,7 @@ void drawContext::drawView() this->drawPost(); if(_showGeom) this->drawGeom(); if(_showMesh) this->drawMesh(); - //this->drawScale(); + this->drawScale(); checkGlError("Draw model,post-pro,..."); } diff --git a/contrib/mobile/drawContext.h b/contrib/mobile/drawContext.h index 8d0b665108b920be1d0df99fc5547154f93c1702..4a00d9bf933709a9504935b524f8157852b3aea1 100644 --- a/contrib/mobile/drawContext.h +++ b/contrib/mobile/drawContext.h @@ -49,7 +49,7 @@ public: float getScale(int i) {if(i>=0 && i<3) return this->_scale[i]; return 0;} void initView(int w, int h); void drawView(); - void drawAxes(double x0=0., double y0=0., double z0=0., double h=0.5); + void drawAxes(float x0=0., float y0=0., float z0=0., float h=0.5); void drawGeom(); void drawMesh(); void drawPost(); diff --git a/contrib/mobile/drawString.cpp b/contrib/mobile/drawString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07e13b166f4a6ffb84bf0be5851ef9aeeef6063f --- /dev/null +++ b/contrib/mobile/drawString.cpp @@ -0,0 +1,73 @@ +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include "drawString.h" + +drawString::drawString(std::string text, int size, float color[4]) +{ + _size = size; + if(color == NULL) + this->setColor(0.0f, 0.0f, 0.0f, 1.0f); + else + this->setColor(color); + this->setText(text); +} + +void drawString::setText(std::string text) +{ + this->_text = text; + getBitmapFromString(this->_text.c_str(), _size, &this->_map, &this->_height, &this->_width, &this->_realWidth); +} + +void drawString::setColor(float color[4]) +{ + _color[0] = color[0]; + _color[1] = color[1]; + _color[2] = color[2]; + _color[3] = color[3]; +} + +void drawString::setColor(float r, float g, float b, float a) +{ + _color[0] = r; + _color[1] = g; + _color[2] = b; + _color[3] = a; +} +void drawString::draw(float x, float y, float z, float w, float h, bool center) +{ + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, _width, _height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, _map); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glColor4f(_color[0], _color[1], _color[2], _color[3]); + if(center) + x-=(float)_realWidth/w/2; + GLfloat vertex[] = { + x, y, z, // bottom left + x, y+(float)_height/h, z, // top left + x+(float)_width/w, y, z, // bottom right + x+(float)_width/w, y+(float)_height/h, z, // top right + }; + GLfloat texture[] = { + 0.0f, 1.0f, // top left + 0.0f, 0.0f, // bottom left + 1.0f, 1.0f, // top right + 1.0f, 0.0f, // bottom right + }; + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_LIGHTING); + glVertexPointer(3, GL_FLOAT, 0, vertex); + glTexCoordPointer(2, GL_FLOAT, 0, texture); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDeleteTextures(1, &textureId); +} diff --git a/contrib/mobile/drawString.h b/contrib/mobile/drawString.h new file mode 100644 index 0000000000000000000000000000000000000000..8a2640bbae61192cf395fe08e4620cd5e61615bd --- /dev/null +++ b/contrib/mobile/drawString.h @@ -0,0 +1,23 @@ +#include <string> + +#include "androidGModel.h" + +class drawString +{ +private: + bool _changed; // UNUSED ?? + std::string _text; // Text to draw + float _color[4]; // Text color + int _size; // Text size in px + int _height, _width, _realWidth; // Size of the texture in px + unsigned char *_map; + +public: + drawString(std::string text, int size=12, float *color=NULL); + ~drawString(){if(_map)free(_map);} + + void setText(std::string text); + void setColor(float *color); + void setColor(float r, float g, float b, float a); + void draw(float x, float y, float z, float w, float h, bool center=true); +};