3dphotoshoot

changeset 9:d1b456d08713

texture matrix and video size from JNI
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 25 May 2015 05:27:26 +0300
parents 9fc7d52f578d
children c71c477521ca
files android/manifest.xml.in src/android/MainActivity.java src/android/camera.c src/camera.h src/game.c
diffstat 5 files changed, 97 insertions(+), 14 deletions(-) [+]
line diff
     1.1 --- a/android/manifest.xml.in	Mon May 25 04:14:38 2015 +0300
     1.2 +++ b/android/manifest.xml.in	Mon May 25 05:27:26 2015 +0300
     1.3 @@ -10,7 +10,7 @@
     1.4  	<uses-feature android:name="android.hardware.camera" />
     1.5  
     1.6  	<application android:label="$APPNAME" android:debuggable="true">
     1.7 -			<!-- android:icon="@drawable/ic_launcher" -->
     1.8 +		<!-- android:icon="@drawable/ic_launcher" -->
     1.9  
    1.10  		<activity android:name="MainActivity" android:label="$APPTITLE"
    1.11  				android:screenOrientation="landscape">
     2.1 --- a/src/android/MainActivity.java	Mon May 25 04:14:38 2015 +0300
     2.2 +++ b/src/android/MainActivity.java	Mon May 25 05:27:26 2015 +0300
     2.3 @@ -24,6 +24,8 @@
     2.4  
     2.5  	// old camera api (fallback)
     2.6  	private static Camera cam;
     2.7 +	private static Camera.Parameters params;
     2.8 +	private static int preview_width, preview_height;
     2.9  	private static SurfaceTexture surftex;
    2.10  
    2.11  	public static int start_video(int texid)
    2.12 @@ -49,10 +51,13 @@
    2.13  
    2.14  		cam = Camera.open(0);
    2.15  
    2.16 -		Camera.Parameters params = cam.getParameters();
    2.17 +		params = cam.getParameters();
    2.18  		params.set("orientation", "landscape");
    2.19  		cam.setParameters(params);
    2.20  
    2.21 +		preview_width = params.getPreviewSize().width;
    2.22 +		preview_height = params.getPreviewSize().height;
    2.23 +
    2.24  		try {
    2.25  			cam.setPreviewTexture(surftex);
    2.26  		}
    2.27 @@ -70,14 +75,18 @@
    2.28  	{
    2.29  		cam.stopPreview();
    2.30  		cam = null;
    2.31 +		params = null;
    2.32  		surftex = null;
    2.33  	}
    2.34  
    2.35 -	public static synchronized void update()
    2.36 +	public static synchronized void update(float [] matrix)
    2.37  	{
    2.38 -		if(cam != null && surftex != null && frame_pending) {
    2.39 -			surftex.updateTexImage();
    2.40 -			frame_pending = false;
    2.41 +		if(cam != null && surftex != null) {
    2.42 +			if(frame_pending) {
    2.43 +				surftex.updateTexImage();
    2.44 +				frame_pending = false;
    2.45 +			}
    2.46 +			surftex.getTransformMatrix(matrix);
    2.47  		}
    2.48  	}
    2.49  }
     3.1 --- a/src/android/camera.c	Mon May 25 04:14:38 2015 +0300
     3.2 +++ b/src/android/camera.c	Mon May 25 05:27:26 2015 +0300
     3.3 @@ -1,4 +1,5 @@
     3.4  #include <stdio.h>
     3.5 +#include <string.h>
     3.6  #include <assert.h>
     3.7  #include <jni.h>
     3.8  #include "opengl.h"
     3.9 @@ -9,6 +10,9 @@
    3.10  static JNIEnv *jni;
    3.11  static jclass activity_class;
    3.12  static unsigned int tex;
    3.13 +static float tex_matrix[16];
    3.14 +static const float identity_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
    3.15 +static jfloatArray jtex_matrix;
    3.16  static int capturing;
    3.17  
    3.18  int cam_init(void *platform_data)
    3.19 @@ -20,6 +24,8 @@
    3.20  	jni = pdata->jni;
    3.21  	activity_class = pdata->activity_class;
    3.22  
    3.23 +	jtex_matrix = (*jni)->NewFloatArray(jni, 16);
    3.24 +
    3.25  	// create the camera texture
    3.26  	assert(glGetError() == GL_NO_ERROR);
    3.27  	glGenTextures(1, &tex);
    3.28 @@ -37,6 +43,10 @@
    3.29  	cam_stop_video();
    3.30  	glDeleteTextures(1, &tex);
    3.31  	tex = 0;
    3.32 +
    3.33 +	if(jni) {
    3.34 +		(*jni)->DeleteGlobalRef(jni, jtex_matrix);
    3.35 +	}
    3.36  }
    3.37  
    3.38  unsigned int cam_texture(void)
    3.39 @@ -44,9 +54,9 @@
    3.40  	return tex;
    3.41  }
    3.42  
    3.43 -void cam_texture_size(int *w, int *h)
    3.44 +const float *cam_texture_matrix(void)
    3.45  {
    3.46 -	/* TODO */
    3.47 +	return tex_matrix;
    3.48  }
    3.49  
    3.50  int cam_start_video(void)
    3.51 @@ -104,7 +114,9 @@
    3.52  
    3.53  int cam_update(void)
    3.54  {
    3.55 +	static int texmat_fail_warned;
    3.56  	jmethodID method;
    3.57 +	float *ptr;
    3.58  
    3.59  	if(!jvm) {
    3.60  		fprintf(stderr, "failed to update camera\n");
    3.61 @@ -114,11 +126,23 @@
    3.62  		return 0;
    3.63  	}
    3.64  
    3.65 -	if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "update", "()V"))) {
    3.66 +	if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "update", "([F)V"))) {
    3.67  		fprintf(stderr, "failed to find static method: update\n");
    3.68  		return -1;
    3.69  	}
    3.70 -	(*jni)->CallStaticVoidMethod(jni, activity_class, method);
    3.71 +	(*jni)->CallStaticVoidMethod(jni, activity_class, method, jtex_matrix);
    3.72 +
    3.73 +	if(!(ptr = (*jni)->GetFloatArrayElements(jni, jtex_matrix, 0))) {
    3.74 +		if(!texmat_fail_warned) {
    3.75 +			fprintf(stderr, "failed to get texture matrix\n");
    3.76 +			texmat_fail_warned = 1;
    3.77 +		}
    3.78 +		memcpy(tex_matrix, identity_matrix, sizeof identity_matrix);
    3.79 +	} else {
    3.80 +		memcpy(tex_matrix, ptr, 16 * sizeof *ptr);
    3.81 +		(*jni)->ReleaseFloatArrayElements(jni, jtex_matrix, ptr, JNI_ABORT);
    3.82 +	}
    3.83 +
    3.84  	return 0;
    3.85  }
    3.86  
    3.87 @@ -127,6 +151,22 @@
    3.88  	return capturing;	// XXX is it better to do this properly through JNI?
    3.89  }
    3.90  
    3.91 +int cam_video_size(int *xsz, int *ysz)
    3.92 +{
    3.93 +	jfieldID jwidth, jheight;
    3.94 +
    3.95 +	if(!(jwidth = (*jni)->GetStaticFieldID(jni, activity_class, "preview_width", "I")) ||
    3.96 +			!(jheight = (*jni)->GetStaticFieldID(jni, activity_class, "preview_height", "I"))) {
    3.97 +		fprintf(stderr, "failed to retrieve preview width/height fields\n");
    3.98 +		*xsz = *ysz = 0;
    3.99 +		return -1;
   3.100 +	}
   3.101 +
   3.102 +	*xsz = (*jni)->GetStaticIntField(jni, activity_class, jwidth);
   3.103 +	*ysz = (*jni)->GetStaticIntField(jni, activity_class, jheight);
   3.104 +	return 0;
   3.105 +}
   3.106 +
   3.107  int cam_take_picture(void)
   3.108  {
   3.109  	return -1;	// TODO
     4.1 --- a/src/camera.h	Mon May 25 04:14:38 2015 +0300
     4.2 +++ b/src/camera.h	Mon May 25 05:27:26 2015 +0300
     4.3 @@ -15,13 +15,15 @@
     4.4  void cam_shutdown(void);
     4.5  
     4.6  unsigned int cam_texture(void);
     4.7 -void cam_texture_size(int *w, int *h);
     4.8 +const float *cam_texture_matrix(void);
     4.9  
    4.10  int cam_start_video(void);
    4.11  int cam_stop_video(void);
    4.12  int cam_update(void);
    4.13  int cam_is_capturing(void);
    4.14  
    4.15 +int cam_video_size(int *xsz, int *ysz);
    4.16 +
    4.17  int cam_take_picture(void);
    4.18  
    4.19  #endif	/* CAMERA_H_ */
     5.1 --- a/src/game.c	Mon May 25 04:14:38 2015 +0300
     5.2 +++ b/src/game.c	Mon May 25 05:27:26 2015 +0300
     5.3 @@ -8,6 +8,9 @@
     5.4  static void draw_quad(float hsz, float vsz);
     5.5  
     5.6  static int win_width, win_height;
     5.7 +static float win_aspect;
     5.8 +static int video_width, video_height;
     5.9 +static float video_aspect;
    5.10  
    5.11  
    5.12  int game_init(void)
    5.13 @@ -19,6 +22,14 @@
    5.14  	glClearColor(0.4, 0.4, 0.4, 1);
    5.15  
    5.16  	cam_start_video();
    5.17 +	cam_video_size(&video_width, &video_height);
    5.18 +	if(video_height) {
    5.19 +		video_aspect = (float)video_width / (float)video_height;
    5.20 +	} else {
    5.21 +		video_aspect = 1.0;
    5.22 +	}
    5.23 +
    5.24 +	printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect);
    5.25  	return 0;
    5.26  }
    5.27  
    5.28 @@ -29,8 +40,13 @@
    5.29  
    5.30  void game_display(unsigned long msec)
    5.31  {
    5.32 -	unsigned int tex = cam_texture();
    5.33 +	unsigned int tex;
    5.34 +	const float *tex_matrix;
    5.35 +	float xscale, yscale;
    5.36 +
    5.37  	cam_update();
    5.38 +	tex = cam_texture();
    5.39 +	tex_matrix = cam_texture_matrix();
    5.40  
    5.41  	//float tsec = (float)msec / 1000.0f;
    5.42  
    5.43 @@ -43,19 +59,34 @@
    5.44  	if(tex) {
    5.45  		glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
    5.46  		glEnable(GL_TEXTURE_EXTERNAL_OES);
    5.47 +
    5.48 +		glMatrixMode(GL_TEXTURE);
    5.49 +		glLoadMatrixf(tex_matrix);
    5.50 +		glMatrixMode(GL_MODELVIEW);
    5.51  	}
    5.52  
    5.53 -	draw_quad(0.5 * 1.33333, 0.5);
    5.54 +	if(video_aspect > win_aspect) {
    5.55 +		xscale = 1.0;
    5.56 +		yscale = 1.0 / video_aspect;
    5.57 +	} else {
    5.58 +		xscale = video_aspect;
    5.59 +		yscale = 1.0;
    5.60 +	}
    5.61 +	draw_quad(xscale, yscale);
    5.62  
    5.63  	if(tex) {
    5.64  		glDisable(GL_TEXTURE_EXTERNAL_OES);
    5.65 +
    5.66 +		glMatrixMode(GL_TEXTURE);
    5.67 +		glLoadIdentity();
    5.68 +		glMatrixMode(GL_MODELVIEW);
    5.69  	}
    5.70  }
    5.71  
    5.72  static void draw_quad(float hsz, float vsz)
    5.73  {
    5.74  	static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
    5.75 -	static const float tcarr[] = {0, 1, 1, 1, 1, 0, 0, 0};
    5.76 +	static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
    5.77  	static const float colarr[] = {1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1};
    5.78  
    5.79  	glPushMatrix();
    5.80 @@ -82,6 +113,7 @@
    5.81  {
    5.82  	win_width = x;
    5.83  	win_height = y;
    5.84 +	win_aspect = y ? (float)x / (float)y : 1.0;
    5.85  	glViewport(0, 0, x, y);
    5.86  
    5.87  	glMatrixMode(GL_PROJECTION);