3dphotoshoot

view src/android/camera.c @ 25:ac80210d5fbe

preparing a pc version for easier development of non-android-specifics
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 18 Jun 2015 03:12:30 +0300
parents d1b456d08713
children
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <jni.h>
5 #include "opengl.h"
6 #include "camera.h"
7 #include "sdr.h"
8 #include "sanegl.h"
11 static JavaVM *jvm;
12 static JNIEnv *jni;
13 static jclass activity_class;
14 static unsigned int tex;
15 static float tex_matrix[16];
16 static const float identity_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
17 static jfloatArray jtex_matrix;
18 static int capturing;
20 static unsigned int sdr_cam;
21 static int aloc_vertex, aloc_texcoord;
24 int cam_init(void *platform_data)
25 {
26 int glerr;
27 struct cam_android_platform_data *pdata = platform_data;
29 jvm = pdata->vm;
30 jni = pdata->jni;
31 activity_class = pdata->activity_class;
33 jtex_matrix = (*jni)->NewFloatArray(jni, 16);
35 // load preview shader
36 if(!(sdr_cam = create_program_load("sdr/vertex.glsl", "sdr/android_cam_preview.p.glsl"))) {
37 return -1;
38 }
39 aloc_vertex = glGetAttribLocation(sdr_cam, "attr_vertex");
40 aloc_texcoord = glGetAttribLocation(sdr_cam, "attr_texcoord");
42 // create the camera texture
43 assert(glGetError() == GL_NO_ERROR);
44 glGenTextures(1, &tex);
45 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
46 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
47 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
49 glerr = glGetError();
50 assert(glerr == GL_NO_ERROR);
51 return glerr == GL_NO_ERROR ? 0 : -1;
52 }
54 void cam_shutdown(void)
55 {
56 cam_stop_video();
57 glDeleteTextures(1, &tex);
58 tex = 0;
60 free_program(sdr_cam);
62 if(jni) {
63 (*jni)->DeleteGlobalRef(jni, jtex_matrix);
64 }
65 }
67 unsigned int cam_texture(void)
68 {
69 return tex;
70 }
72 const float *cam_texture_matrix(void)
73 {
74 return tex_matrix;
75 }
77 int cam_start_video(void)
78 {
79 jmethodID method;
81 if(!jvm) {
82 fprintf(stderr, "failed to start video, camera not initialized\n");
83 return -1;
84 }
85 if(cam_is_capturing()) {
86 return 0;
87 }
89 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "start_video", "(I)I"))) {
90 fprintf(stderr, "failed to find static method: start_video\n");
91 return -1;
92 }
93 if((*jni)->CallStaticIntMethod(jni, activity_class, method, tex) == -1) {
94 fprintf(stderr, "failed to start video capture\n");
95 capturing = 0;
96 return -1;
97 }
98 capturing = 1;
100 printf("video started\n");
102 return 1;
103 }
105 int cam_stop_video(void)
106 {
107 jmethodID method;
109 if(!jvm) {
110 fprintf(stderr, "failed to stop video, camera not initialized\n");
111 return -1;
112 }
114 if(!cam_is_capturing()) {
115 return 0;
116 }
118 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "stop_video", "()V"))) {
119 fprintf(stderr, "failed to find static method: stop_video\n");
120 return -1;
121 }
122 (*jni)->CallStaticVoidMethod(jni, activity_class, method);
123 capturing = 0;
125 printf("video stopped\n");
127 return 0;
128 }
130 int cam_update(void)
131 {
132 static int texmat_fail_warned;
133 jmethodID method;
134 float *ptr;
136 if(!jvm) {
137 fprintf(stderr, "failed to update camera\n");
138 return -1;
139 }
140 if(!cam_is_capturing()) {
141 return 0;
142 }
144 if(!(method = (*jni)->GetStaticMethodID(jni, activity_class, "update", "([F)V"))) {
145 fprintf(stderr, "failed to find static method: update\n");
146 return -1;
147 }
148 (*jni)->CallStaticVoidMethod(jni, activity_class, method, jtex_matrix);
150 if(!(ptr = (*jni)->GetFloatArrayElements(jni, jtex_matrix, 0))) {
151 if(!texmat_fail_warned) {
152 fprintf(stderr, "failed to get texture matrix\n");
153 texmat_fail_warned = 1;
154 }
155 memcpy(tex_matrix, identity_matrix, sizeof identity_matrix);
156 } else {
157 memcpy(tex_matrix, ptr, 16 * sizeof *ptr);
158 (*jni)->ReleaseFloatArrayElements(jni, jtex_matrix, ptr, JNI_ABORT);
159 }
161 return 0;
162 }
164 int cam_is_capturing(void)
165 {
166 return capturing; // XXX is it better to do this properly through JNI?
167 }
169 int cam_video_size(int *xsz, int *ysz)
170 {
171 jfieldID jwidth, jheight;
173 if(!(jwidth = (*jni)->GetStaticFieldID(jni, activity_class, "preview_width", "I")) ||
174 !(jheight = (*jni)->GetStaticFieldID(jni, activity_class, "preview_height", "I"))) {
175 fprintf(stderr, "failed to retrieve preview width/height fields\n");
176 *xsz = *ysz = 0;
177 return -1;
178 }
180 *xsz = (*jni)->GetStaticIntField(jni, activity_class, jwidth);
181 *ysz = (*jni)->GetStaticIntField(jni, activity_class, jheight);
182 return 0;
183 }
185 int cam_take_picture(void)
186 {
187 return -1; // TODO
188 }
190 void cam_draw_preview(void)
191 {
192 const float *tex_matrix = cam_texture_matrix();
194 gl_matrix_mode(GL_TEXTURE);
195 gl_load_matrixf(tex_matrix);
197 glUseProgram(sdr_cam);
198 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
200 gl_begin(GL_QUADS);
201 gl_texcoord2f(0, 0);
202 gl_vertex2f(-1, -1);
203 gl_texcoord2f(1, 0);
204 gl_vertex2f(1, -1);
205 gl_texcoord2f(1, 1);
206 gl_vertex2f(1, 1);
207 gl_texcoord2f(0, 1);
208 gl_vertex2f(-1, 1);
209 gl_end();
211 gl_matrix_mode(GL_TEXTURE);
212 gl_load_identity();
213 }