• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // This modules handles drawing the passthrough camera image into the OpenGL
18 // scene.
19 
20 #include <type_traits>
21 
22 #include "platform_tools/android/apps/arcore/src/main/cpp/background_renderer.h"
23 
24 namespace hello_ar {
25     namespace {
26 // Positions of the quad vertices in clip space (X, Y, Z).
27         const GLfloat kVertices[] = {
28                 -1.0f, -1.0f, 0.0f, +1.0f, -1.0f, 0.0f,
29                 -1.0f, +1.0f, 0.0f, +1.0f, +1.0f, 0.0f,
30         };
31 
32 // UVs of the quad vertices (S, T)
33         const GLfloat kUvs[] = {
34                 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
35         };
36 
37         constexpr char kVertexShader[] = R"(
38     attribute vec4 vertex;
39     attribute vec2 textureCoords;
40     varying vec2 v_textureCoords;
41     void main() {
42       v_textureCoords = textureCoords;
43       gl_Position = vertex;
44     })";
45 
46         constexpr char kFragmentShader[] = R"(
47     #extension GL_OES_EGL_image_external : require
48     precision mediump float;
49     uniform samplerExternalOES texture;
50     varying vec2 v_textureCoords;
51     void main() {
52       gl_FragColor = texture2D(texture, v_textureCoords);
53     })";
54 
55     }  // namespace
56 
InitializeGlContent()57     void BackgroundRenderer::InitializeGlContent() {
58         shader_program_ = util::CreateProgram(kVertexShader, kFragmentShader);
59 
60         if (!shader_program_) {
61             LOGE("Could not create program.");
62         }
63 
64         glGenTextures(1, &texture_id_);
65         glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
66         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
67         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
68 
69         uniform_texture_ = glGetUniformLocation(shader_program_, "texture");
70         attribute_vertices_ = glGetAttribLocation(shader_program_, "vertex");
71         attribute_uvs_ = glGetAttribLocation(shader_program_, "textureCoords");
72     }
73 
Draw(const ArSession * session,const ArFrame * frame)74     void BackgroundRenderer::Draw(const ArSession *session, const ArFrame *frame) {
75         static_assert(std::extent<decltype(kUvs)>::value == kNumVertices * 2,
76                       "Incorrect kUvs length");
77         static_assert(std::extent<decltype(kVertices)>::value == kNumVertices * 3,
78                       "Incorrect kVertices length");
79 
80         // If display rotation changed (also includes view size change), we need to
81         // re-query the uv coordinates for the on-screen portion of the camera image.
82         int32_t geometry_changed = 0;
83         ArFrame_getDisplayGeometryChanged(session, frame, &geometry_changed);
84         if (geometry_changed != 0 || !uvs_initialized_) {
85             ArFrame_transformDisplayUvCoords(session, frame, kNumVertices * 2, kUvs,
86                                              transformed_uvs_);
87             uvs_initialized_ = true;
88         }
89         glUseProgram(shader_program_);
90         glDepthMask(GL_FALSE);
91 
92         glUniform1i(uniform_texture_, 1);
93         glActiveTexture(GL_TEXTURE1);
94         glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
95 
96         glEnableVertexAttribArray(attribute_vertices_);
97         glVertexAttribPointer(attribute_vertices_, 3, GL_FLOAT, GL_FALSE, 0,
98                               kVertices);
99 
100         glEnableVertexAttribArray(attribute_uvs_);
101         glVertexAttribPointer(attribute_uvs_, 2, GL_FLOAT, GL_FALSE, 0,
102                               transformed_uvs_);
103 
104         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
105 
106         glUseProgram(0);
107         glDepthMask(GL_TRUE);
108         util::CheckGlError("BackgroundRenderer::Draw() error");
109     }
110 
GetTextureId() const111     GLuint BackgroundRenderer::GetTextureId() const { return texture_id_; }
112 
113 }  // namespace hello_ar
114