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);