11#include " alvr_client_core.h"
22#include " cardboard.h"
33#include < GLES3/gl3.h>
4- #include < GLES2/gl2ext.h>
54#include < algorithm>
65#include < deque>
76#include < jni.h>
1110#include < vector>
1211
1312#include " common.h"
13+ #include " passthrough.h"
1414
1515void log (AlvrLogLevel level, const char *format, ...) {
1616 va_list args;
@@ -44,65 +44,6 @@ struct Pose {
4444 AlvrQuat orientation;
4545};
4646
47- GLuint LoadGLShader (GLenum type, const char *shader_source) {
48- GLuint shader = glCreateShader (type);
49- glShaderSource (shader, 1 , &shader_source, nullptr );
50- glCompileShader (shader);
51-
52- // Get the compilation status.
53- GLint compile_status;
54- glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status);
55-
56- // If the compilation failed, delete the shader and show an error.
57- if (compile_status == 0 ) {
58- GLint info_len = 0 ;
59- glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &info_len);
60- if (info_len == 0 ) {
61- return 0 ;
62- }
63-
64- std::vector<char > info_string (info_len);
65- glGetShaderInfoLog (shader, info_string.size (), nullptr , info_string.data ());
66- // LOGE("Could not compile shader of type %d: %s", type, info_string.data());
67- glDeleteShader (shader);
68- return 0 ;
69- } else {
70- return shader;
71- }
72- }
73-
74- namespace {
75- // Simple shaders to render camera Texture files without any lighting.
76- constexpr const char *camVertexShader =
77- R"glsl(
78- uniform mat4 u_MVP;
79- attribute vec4 a_Position;
80- attribute vec2 a_UV;
81- varying vec2 v_UV;
82-
83- void main() {
84- v_UV = a_UV;
85- gl_Position = a_Position;
86- })glsl" ;
87-
88- constexpr const char *camFragmentShader =
89- R"glsl(
90- #extension GL_OES_EGL_image_external : require
91- precision mediump float;
92- varying vec2 v_UV;
93- uniform samplerExternalOES sTexture;
94- void main() {
95- gl_FragColor = texture2D(sTexture, v_UV);
96- })glsl" ;
97-
98- static int passthrough_program_ = 0 ;
99- static int texture_position_param_ = 0 ;
100- static int texture_uv_param_ = 0 ;
101- static int texture_mvp_param_ = 0 ;
102-
103- float passthrough_tex_coords[] = {0.0 , 1.0 , 1.0 , 1.0 , 0.0 , 0.0 , 1.0 , 0.0 };
104- } // namespace
105-
10647struct NativeContext {
10748 JavaVM *javaVm = nullptr ;
10849 jobject javaContext = nullptr ;
@@ -119,24 +60,13 @@ struct NativeContext {
11960
12061 bool running = false ;
12162 bool streaming = false ;
122- bool passthrough = false ;
63+ PassthroughInfo passthroughInfo = {} ;
12364 std::thread inputThread;
12465
12566 // Une one texture per eye, no need for swapchains.
12667 GLuint lobbyTextures[2 ] = {};
12768 GLuint streamTextures[2 ] = {};
12869
129- GLuint cameraTexture = 0 ;
130- GLuint passthroughTexture = 0 ;
131- CardboardEyeTextureDescription passthrough_left_eye;
132- CardboardEyeTextureDescription passthrough_right_eye;
133-
134- GLuint passthroughDepthRenderBuffer = 0 ;
135- GLuint passthroughFramebuffer = 0 ;
136-
137- float passthrough_vertices[8 ];
138- float passthrough_size = 1.0 ;
139-
14070 float eyeOffsets[2 ] = {};
14171};
14272
@@ -210,23 +140,6 @@ Pose getPose(uint64_t timestampNs) {
210140 return pose;
211141}
212142
213- void createPassthroughPlane (NativeContext *ctx) {
214- float size = ctx->passthrough_size ;
215- float x0 = -size, y0 = size; // Top left
216- float x1 = size, y1 = size; // Top right
217- float x2 = size, y2 = -size; // Bottom right
218- float x3 = -size, y3 = -size; // Bottom left
219-
220- ctx->passthrough_vertices [0 ] = x3;
221- ctx->passthrough_vertices [1 ] = y3;
222- ctx->passthrough_vertices [2 ] = x2;
223- ctx->passthrough_vertices [3 ] = y2;
224- ctx->passthrough_vertices [4 ] = x0;
225- ctx->passthrough_vertices [5 ] = y0;
226- ctx->passthrough_vertices [6 ] = x1;
227- ctx->passthrough_vertices [7 ] = y1;
228- }
229-
230143void inputThread () {
231144 auto deadline = std::chrono::steady_clock::now ();
232145
@@ -276,7 +189,10 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_initia
276189
277190 Cardboard_initializeAndroid (CTX.javaVm , CTX.javaContext );
278191 CTX.headTracker = CardboardHeadTracker_create ();
279- createPassthroughPlane (&CTX);
192+
193+ CTX.passthroughInfo .screenWidth = &(CTX.screenWidth );
194+ CTX.passthroughInfo .screenHeight = &(CTX.screenHeight );
195+ passthrough_createPlane (&(CTX.passthroughInfo ));
280196}
281197
282198extern " C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_destroyNative (JNIEnv *,
@@ -323,45 +239,22 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_pauseN
323239
324240extern " C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_Passthrough_setPassthroughActiveNative (
325241 JNIEnv *, jobject, jboolean activate) {
326- CTX.passthrough = activate;
242+ CTX.passthroughInfo . enabled = activate;
327243 CTX.renderingParamsChanged = true ;
328244}
329245
330246extern " C" JNIEXPORT void JNICALL
331247Java_viritualisres_phonevr_Passthrough_setPassthroughSizeNative (JNIEnv *, jobject, jfloat size) {
332- CTX.passthrough_size = size;
333- createPassthroughPlane (& CTX);
248+ CTX.passthroughInfo . passthroughSize = size;
249+ passthrough_createPlane (&( CTX. passthroughInfo ) );
334250}
335251
336252extern " C" JNIEXPORT jint JNICALL
337253Java_viritualisres_phonevr_ALVRActivity_surfaceCreatedNative (JNIEnv *, jobject) {
338254 alvr_initialize_opengl ();
339-
340- const int obj_vertex_shader = LoadGLShader (GL_VERTEX_SHADER, camVertexShader);
341- const int obj_fragment_shader = LoadGLShader (GL_FRAGMENT_SHADER, camFragmentShader);
342-
343- passthrough_program_ = glCreateProgram ();
344- glAttachShader (passthrough_program_, obj_vertex_shader);
345- glAttachShader (passthrough_program_, obj_fragment_shader);
346- glLinkProgram (passthrough_program_);
347-
348- glUseProgram (passthrough_program_);
349- texture_position_param_ = glGetAttribLocation (passthrough_program_, " a_Position" );
350- texture_uv_param_ = glGetAttribLocation (passthrough_program_, " a_UV" );
351- texture_mvp_param_ = glGetUniformLocation (passthrough_program_, " u_MVP" );
352-
353- // TODO initialize plane mesh and texture
354- glGenTextures (1 , &CTX.cameraTexture );
355- glActiveTexture (GL_TEXTURE0);
356-
357- glBindTexture (GL_TEXTURE_EXTERNAL_OES, CTX.cameraTexture );
358- glTexParameterf (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
359- glTexParameterf (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
360- glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
361- glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
362-
255+ GLuint camTex = passthrough_init (&(CTX.passthroughInfo ));
363256 CTX.glContextRecreated = true ;
364- return CTX. cameraTexture ;
257+ return camTex ;
365258}
366259
367260extern " C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_setScreenResolutionNative (
@@ -377,54 +270,6 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_sendBa
377270 alvr_send_battery (HEAD_ID, level, plugged);
378271}
379272
380- void cleanupPassthrough () {
381- if (CTX.passthroughDepthRenderBuffer != 0 ) {
382- glDeleteRenderbuffers (1 , &CTX.passthroughDepthRenderBuffer );
383- CTX.passthroughDepthRenderBuffer = 0 ;
384- }
385- if (CTX.passthroughFramebuffer != 0 ) {
386- glDeleteFramebuffers (1 , &CTX.passthroughFramebuffer );
387- CTX.passthroughFramebuffer = 0 ;
388- }
389- if (CTX.passthroughTexture != 0 ) {
390- glDeleteTextures (1 , &CTX.passthroughTexture );
391- CTX.passthroughTexture = 0 ;
392- }
393- }
394-
395- void passthroughSetup () {
396- // Create render texture.
397- glGenTextures (1 , &CTX.passthroughTexture );
398- glBindTexture (GL_TEXTURE_2D, CTX.passthroughTexture );
399- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
400- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
401- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
402- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
403-
404- glTexImage2D (GL_TEXTURE_2D,
405- 0 ,
406- GL_RGB,
407- CTX.screenWidth ,
408- CTX.screenHeight ,
409- 0 ,
410- GL_RGB,
411- GL_UNSIGNED_BYTE,
412- 0 );
413-
414- // Generate depth buffer to perform depth test.
415- glGenRenderbuffers (1 , &CTX.passthroughDepthRenderBuffer );
416- glBindRenderbuffer (GL_RENDERBUFFER, CTX.passthroughDepthRenderBuffer );
417- glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, CTX.screenWidth , CTX.screenHeight );
418-
419- // Create render target.
420- glGenFramebuffers (1 , &CTX.passthroughFramebuffer );
421- glBindFramebuffer (GL_FRAMEBUFFER, CTX.passthroughFramebuffer );
422- glFramebufferTexture2D (
423- GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CTX.passthroughTexture , 0 );
424- glFramebufferRenderbuffer (
425- GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, CTX.passthroughDepthRenderBuffer );
426- }
427-
428273extern " C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_renderNative (JNIEnv *,
429274 jobject) {
430275 if (CTX.renderingParamsChanged ) {
@@ -449,11 +294,6 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_render
449294 CardboardQrCode_destroy (buffer);
450295 *buffer = 0 ;
451296
452- // cleanupPassthrough();
453- // if (CTX.passthrough){
454- // passthroughSetup();
455- // }
456-
457297 if (CTX.distortionRenderer ) {
458298 CardboardDistortionRenderer_destroy (CTX.distortionRenderer );
459299 CTX.distortionRenderer = nullptr ;
@@ -481,13 +321,13 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_render
481321 if (CTX.renderingParamsChanged && !CTX.glContextRecreated ) {
482322 info (" Pausing ALVR since glContext is not recreated, deleting textures" );
483323 alvr_pause_opengl ();
484- cleanupPassthrough ( );
324+ passthrough_cleanup (&(CTX. passthroughInfo ) );
485325 glDeleteTextures (2 , CTX.lobbyTextures );
486326 }
487327
488328 if (CTX.renderingParamsChanged || CTX.glContextRecreated ) {
489- if (CTX.passthrough ) {
490- passthroughSetup ( );
329+ if (CTX.passthroughInfo . enabled ) {
330+ passthrough_setup (&(CTX. passthroughInfo ) );
491331 } else {
492332 info (" Rebuilding, binding textures, Resuming ALVR since glContextRecreated %b, "
493333 " renderingParamsChanged %b" ,
@@ -600,39 +440,8 @@ extern "C" JNIEXPORT void JNICALL Java_viritualisres_phonevr_ALVRActivity_render
600440 viewsDesc.bottom_v = 0.0 ;
601441 }
602442
603- if (CTX.passthrough ) {
604- glBindFramebuffer (GL_FRAMEBUFFER, CTX.passthroughFramebuffer );
605-
606- glEnable (GL_DEPTH_TEST);
607- glEnable (GL_CULL_FACE);
608- glDisable (GL_SCISSOR_TEST);
609- glEnable (GL_BLEND);
610- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
611- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
612-
613- // Draw Passthrough video for each eye
614- for (int eye = 0 ; eye < 2 ; ++eye) {
615- glViewport (
616- eye == kLeft ? 0 : CTX.screenWidth / 2 , 0 , CTX.screenWidth / 2 , CTX.screenHeight );
617-
618- glUseProgram (passthrough_program_);
619- glActiveTexture (GL_TEXTURE0);
620- glBindTexture (GL_TEXTURE_EXTERNAL_OES, CTX.cameraTexture );
621-
622- // Draw Mesh
623- glEnableVertexAttribArray (texture_position_param_);
624- glVertexAttribPointer (
625- texture_position_param_, 2 , GL_FLOAT, false , 0 , CTX.passthrough_vertices );
626- glEnableVertexAttribArray (texture_uv_param_);
627- glVertexAttribPointer (texture_uv_param_, 2 , GL_FLOAT, false , 0 , passthrough_tex_coords);
628-
629- glDrawArrays (GL_TRIANGLE_STRIP, 0 , 4 );
630-
631- viewsDescs[eye].left_u = 0.5 * eye; // 0 for left, 0.5 for right
632- viewsDescs[eye].right_u = 0.5 + 0.5 * eye; // 0.5 for left, 1.0 for right
633- }
634- viewsDescs[0 ].texture = CTX.passthroughTexture ;
635- viewsDescs[1 ].texture = CTX.passthroughTexture ;
443+ if (CTX.passthroughInfo .enabled ) {
444+ passthrough_render (&(CTX.passthroughInfo ), viewsDescs);
636445 } else if (CTX.streaming ) {
637446 void *streamHardwareBuffer = nullptr ;
638447 auto timestampNs = alvr_get_frame (&streamHardwareBuffer);
0 commit comments