Eh bien, voici comment je l'ai fait ... J'espère que quelqu'un le trouve utile si le Qualcomm AR est sorti .. il peut être obsolète .. oh et fondamentalement ce que cela fait est - générer deux cubes funky de cet exemple Android, les fonctionnalités supplémentaires introduites sont les événements tactiles, bien que les vecteurs de rotation soient très éloignés - juste dans un but de démonstration de toute façon et bien sûr les cubes superposés au-dessus de l'aperçu de la caméra qui peut être déplacé sur un écran ..
public class TakeRecieptPicture extends Activity implements Callback {
private Camera camera;
private SurfaceView mSurfaceView;
SurfaceHolder mSurfaceHolder;
private TouchSurfaceView mGLSurfaceView;
ShutterCallback shutter = new ShutterCallback(){
@Override
public void onShutter() {
// TODO Auto-generated method stub
// No action to be perfomed on the Shutter callback.
}
};
PictureCallback raw = new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
// No action taken on the raw data. Only action taken on jpeg data.
}
};
PictureCallback jpeg = new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
FileOutputStream outStream = null;
try{
outStream = new FileOutputStream("/sdcard/test.jpg");
outStream.write(data);
outStream.close();
}catch(FileNotFoundException e){
Log.d("Camera", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("Camera", e.getMessage());
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGLSurfaceView = new TouchSurfaceView(this);
addContentView(mGLSurfaceView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
mSurfaceView = new SurfaceView(this);
addContentView(mSurfaceView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT|LayoutParams.FLAG_BLUR_BEHIND);
}
private void takePicture() {
// TODO Auto-generated method stub
camera.takePicture(shutter, raw, jpeg);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(arg2, arg3);
try {
camera.setPreviewDisplay(arg0);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
}
}
Le TouchSurfaceView est défini ci-dessous:
class TouchSurfaceView extends GLSurfaceView {
public TouchSurfaceView(Context context) {
super(context);
cr = new CubeRenderer(true);
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.setRenderer(cr);
this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
this.getHolder().setFormat(PixelFormat.TRANSPARENT);
}
public boolean onTrackballEvent(MotionEvent e) {
cr.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
cr.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
requestRender();
return true; }
@Override
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
cr.mAngleX += dx * TOUCH_SCALE_FACTOR;
cr.mAngleY += dy * TOUCH_SCALE_FACTOR;
requestRender();
}
mPreviousX = x;
mPreviousY = y;
return true;
}
private final float TOUCH_SCALE_FACTOR = 180.0f/320;
private final float TRACKBALL_SCALE_FACTOR = 36.0f;
public CubeRenderer cr ;
private float mPreviousX;
private float mPreviousY;
}
Et le CubeRenderer est donnée par:
class CubeRenderer implements GLSurfaceView.Renderer {
public CubeRenderer(boolean useTranslucentBackground) {
mTranslucentBackground = useTranslucentBackground;
mCube = new Cube();
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5.0f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mCube.draw(gl);
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
gl.glTranslatef(0.5f, 0.5f, 0.5f);
mCube.draw(gl);
mAngle += 1.2f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float) width/height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0,0,0,0);
} else {
gl.glClearColor(1,1,1,1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
public void setAngle(float _angle){
}
private boolean mTranslucentBackground;
private Cube mCube;
private float mAngle;
public float mAngleX;
public float mAngleY;
}
Et enfin le cube lui-même est donné par:
class Cube{
public Cube()
{ int one = 0x10000;
int vertices[] = {
-one, -one, -one,
one, -one, -one,
one, one, -one,
-one, one, -one,
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one, };
float[] colors = {
0f, 0f, 0f, 0.5f,
1f , 0f, 0f, 0.1f,
1f,1f,0f,0.5f,
0f, 1f, 0f, 0.1f,
0f, 0f, 1f, 0.1f,
1f, 0f, 1f, 0.2f,
1f, 1f, 1f, 0.1f,
0f, 1f, 1f, 0.1f, };
byte indices[] = {
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2 };
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0); }
public void draw(GL10 gl) {
gl.glFrontFace(gl.GL_CW);
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer); }
private IntBuffer mVertexBuffer;
private FloatBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
Eh bien, espérons que quelqu'un trouve cela utile ...
Ma classe DrawonTop étend également SurfaceView et implémente l'interface SurfaceHolder.Callback. Pensez-vous que cela me causera des problèmes si j'essaie de le superposer sur l'aperçu de la caméra? J'ai lu que SurfaceViews ne peut pas être transparent, mais je me demande si c'est juste un tas de foutaises. – GobiasKoffi
En plus de cela, la classe DrawOnTop ne doit-elle pas être appelée dans une sorte d'UIthread? Ce n'est pas fait dans l'exemple que vous avez suggéré. – GobiasKoffi
Le lien ne fonctionne plus. –