Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
| 6 | 6 |
| 7 #include "chrome/browser/android/vr_shell/vr_util.h" | 7 #include "chrome/browser/android/vr_shell/vr_util.h" |
| 8 #include "ui/gl/gl_bindings.h" | 8 #include "ui/gl/gl_bindings.h" |
| 9 | 9 |
| 10 namespace vr_shell { | 10 namespace vr_shell { |
| 11 | 11 |
| 12 namespace { | 12 namespace { |
| 13 | 13 |
| 14 const float kHalfHeight = 0.5f; | 14 const float kHalfHeight = 0.5f; |
| 15 const float kHalfWidth = 0.5f; | 15 const float kHalfWidth = 0.5f; |
| 16 const float kTextureQuadPosition[18] = { | 16 const float kTextureQuadPosition[18] = { |
| 17 -kHalfWidth, kHalfHeight, 0.0f, -kHalfWidth, -kHalfHeight, 0.0f, | 17 -kHalfWidth, kHalfHeight, 0.0f, -kHalfWidth, -kHalfHeight, 0.0f, |
| 18 kHalfWidth, kHalfHeight, 0.0f, -kHalfWidth, -kHalfHeight, 0.0f, | 18 kHalfWidth, kHalfHeight, 0.0f, -kHalfWidth, -kHalfHeight, 0.0f, |
| 19 kHalfWidth, -kHalfHeight, 0.0f, kHalfWidth, kHalfHeight, 0.0f}; | 19 kHalfWidth, -kHalfHeight, 0.0f, kHalfWidth, kHalfHeight, 0.0f}; |
| 20 const int kPositionDataSize = 3; | 20 const int kPositionDataSize = 3; |
| 21 // Number of vertices passed to glDrawArrays(). | 21 // Number of vertices passed to glDrawArrays(). |
| 22 const int kVerticesNumber = 6; | 22 const int kVerticesNumber = 6; |
| 23 | 23 |
| 24 const float kTexturedQuadTextureCoordinates[12] = { | 24 const float kTexturedQuadTextureCoordinates[12] = { |
| 25 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; | 25 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| 26 const int kTextureCoordinateDataSize = 2; | 26 const int kTextureCoordinateDataSize = 2; |
| 27 | 27 |
| 28 #define SHADER(Src) #Src | 28 #define SHADER(Src) #Src |
| 29 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src | 29 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src |
| 30 #define VOID_OFFSET(x) reinterpret_cast<void*>(x) | |
| 30 | 31 |
| 31 const char* GetShaderSource(ShaderID shader) { | 32 const char* GetShaderSource(ShaderID shader) { |
| 32 switch (shader) { | 33 switch (shader) { |
| 33 case TEXTURE_QUAD_VERTEX_SHADER: | 34 case TEXTURE_QUAD_VERTEX_SHADER: |
| 34 return SHADER(uniform mat4 u_CombinedMatrix; attribute vec4 a_Position; | 35 return SHADER(uniform mat4 u_CombinedMatrix; attribute vec4 a_Position; |
| 35 attribute vec2 a_TexCoordinate; | 36 attribute vec2 a_TexCoordinate; |
| 36 varying vec2 v_TexCoordinate; void main() { | 37 varying vec2 v_TexCoordinate; void main() { |
| 37 v_TexCoordinate = a_TexCoordinate; | 38 v_TexCoordinate = a_TexCoordinate; |
| 38 gl_Position = u_CombinedMatrix * a_Position; | 39 gl_Position = u_CombinedMatrix * a_Position; |
| 39 }); | 40 }); |
| 40 case TEXTURE_QUAD_FRAGMENT_SHADER: | 41 case TEXTURE_QUAD_FRAGMENT_SHADER: |
| 41 return OEIE_SHADER( | 42 return OEIE_SHADER( |
| 42 precision highp float; uniform samplerExternalOES u_Texture; | 43 precision highp float; uniform samplerExternalOES u_Texture; |
| 43 varying vec2 v_TexCoordinate; void main() { | 44 varying vec2 v_TexCoordinate; void main() { |
| 44 vec4 texture = texture2D(u_Texture, v_TexCoordinate); | 45 vec4 texture = texture2D(u_Texture, v_TexCoordinate); |
| 45 gl_FragColor = vec4(texture.r, texture.g, texture.b, 1.0); | 46 gl_FragColor = vec4(texture.r, texture.g, texture.b, 1.0); |
| 46 }); | 47 }); |
| 48 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: | |
| 49 return SHADER( | |
| 50 attribute vec2 a_Position; | |
| 51 attribute vec2 a_TexCoordinate; | |
| 52 uniform vec4 u_SrcRect; | |
| 53 varying vec2 v_TexCoordinate; | |
| 54 | |
| 55 void main() { | |
| 56 v_TexCoordinate = u_SrcRect.xy + (a_TexCoordinate * u_SrcRect.zw); | |
| 57 gl_Position = vec4(a_Position, 0.0, 1.0); | |
| 58 }); | |
| 59 case vr_shell::ShaderID::WEBVR_FRAGMENT_SHADER: | |
| 60 return OEIE_SHADER( | |
| 61 precision highp float; | |
| 62 uniform samplerExternalOES u_Texture; | |
| 63 varying vec2 v_TexCoordinate; | |
| 64 | |
| 65 void main() { | |
| 66 gl_FragColor = texture2D(u_Texture, v_TexCoordinate); | |
| 67 }); | |
| 47 default: | 68 default: |
| 48 LOG(ERROR) << "Shader source requested for unknown shader"; | 69 LOG(ERROR) << "Shader source requested for unknown shader"; |
| 49 return ""; | 70 return ""; |
| 50 } | 71 } |
| 51 } | 72 } |
| 52 | 73 |
| 53 } // namespace | 74 } // namespace |
| 54 | 75 |
| 55 TexturedQuadRenderer::TexturedQuadRenderer() { | 76 TexturedQuadRenderer::TexturedQuadRenderer() { |
| 56 std::string error; | 77 std::string error; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 | 132 |
| 112 glDisableVertexAttribArray(position_handle_); | 133 glDisableVertexAttribArray(position_handle_); |
| 113 glDisableVertexAttribArray(texture_coordinate_handle_); | 134 glDisableVertexAttribArray(texture_coordinate_handle_); |
| 114 } | 135 } |
| 115 | 136 |
| 116 TexturedQuadRenderer::~TexturedQuadRenderer() { | 137 TexturedQuadRenderer::~TexturedQuadRenderer() { |
| 117 glDeleteShader(vertex_shader_handle_); | 138 glDeleteShader(vertex_shader_handle_); |
| 118 glDeleteShader(fragment_shader_handle_); | 139 glDeleteShader(fragment_shader_handle_); |
| 119 } | 140 } |
| 120 | 141 |
| 142 WebVrRenderer::WebVrRenderer() { | |
| 143 left_bounds_ = { 0.0f, 0.0f, 0.5f, 1.0f }; | |
| 144 right_bounds_ = { 0.5f, 0.0f, 0.5f, 1.0f }; | |
| 145 | |
| 146 std::string error; | |
| 147 GLuint vertex_shader_handle = CompileShader( | |
| 148 GL_VERTEX_SHADER, GetShaderSource(WEBVR_VERTEX_SHADER), error); | |
| 149 if (vertex_shader_handle == 0) { | |
| 150 LOG(ERROR) << error; | |
| 151 exit(1); | |
| 152 } | |
| 153 GLuint fragment_shader_handle = CompileShader( | |
| 154 GL_FRAGMENT_SHADER, GetShaderSource(WEBVR_FRAGMENT_SHADER), error); | |
| 155 if (fragment_shader_handle == 0) { | |
| 156 LOG(ERROR) << error; | |
| 157 exit(1); | |
| 158 } | |
| 159 | |
| 160 program_handle_ = CreateAndLinkProgram( | |
| 161 vertex_shader_handle, fragment_shader_handle, 2, nullptr, error); | |
| 162 if (program_handle_ == 0) { | |
| 163 LOG(ERROR) << error; | |
| 164 exit(1); | |
| 165 } | |
| 166 | |
| 167 // Once the program is linked the shader objects are no longer needed | |
| 168 glDeleteShader(vertex_shader_handle); | |
| 169 glDeleteShader(fragment_shader_handle); | |
| 170 | |
| 171 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | |
| 172 src_rect_uniform_handle_ = glGetUniformLocation(program_handle_, "u_SrcRect"); | |
| 173 position_handle_ = glGetAttribLocation(program_handle_, "a_Position"); | |
| 174 texcoord_handle_ = glGetAttribLocation(program_handle_, "a_TexCoordinate"); | |
| 175 | |
| 176 std::unique_ptr<float> vertices(new float[32]{ | |
|
mthiesse
2016/09/04 16:04:03
Move this out to a constant?
| |
| 177 // x y u, v | |
| 178 -1.f, 1.f, 0.f, 0.f, | |
| 179 -1.f, -1.f, 0.f, 1.f, | |
| 180 0.f, -1.f, 1.f, 1.f, | |
| 181 0.f, 1.f, 1.f, 0.f, | |
| 182 | |
| 183 0.f, 1.f, 0.f, 0.f, | |
| 184 0.f, -1.f, 0.f, 1.f, | |
| 185 1.f, -1.f, 1.f, 1.f, | |
| 186 1.f, 1.f, 1.f, 0.f }); | |
| 187 size_t vertices_size = sizeof(float) * 32; | |
| 188 | |
| 189 // TODO: Figure out why this need to be restored. | |
| 190 GLint old_buffer; | |
| 191 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); | |
| 192 | |
| 193 glGenBuffersARB(1, &vertex_buffer_); | |
| 194 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
| 195 glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices.get(), GL_STATIC_DRAW); | |
| 196 | |
| 197 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | |
| 198 } | |
| 199 | |
| 200 /** | |
| 201 * Draw the WebVR frame | |
| 202 */ | |
| 203 void WebVrRenderer::Draw(int texture_handle) { | |
| 204 // TODO: Figure out why this need to be restored. | |
| 205 GLint old_buffer; | |
| 206 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); | |
| 207 | |
| 208 glUseProgram(program_handle_); | |
| 209 | |
| 210 // Bind vertex attributes | |
| 211 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
| 212 | |
| 213 glEnableVertexAttribArray(position_handle_); | |
| 214 glEnableVertexAttribArray(texcoord_handle_); | |
| 215 | |
| 216 glVertexAttribPointer(position_handle_, POSITION_ELEMENTS, GL_FLOAT, false, | |
| 217 VERTEX_STRIDE, VOID_OFFSET(POSITION_OFFSET)); | |
| 218 glVertexAttribPointer(texcoord_handle_, TEXCOORD_ELEMENTS, GL_FLOAT, false, | |
| 219 VERTEX_STRIDE, VOID_OFFSET(TEXCOORD_OFFSET)); | |
| 220 | |
| 221 // Bind texture. | |
| 222 glActiveTexture(GL_TEXTURE0); | |
| 223 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle); | |
| 224 glUniform1i(tex_uniform_handle_, 0); | |
| 225 | |
| 226 // TODO: Should be able handle both eyes in a single draw call. | |
| 227 // Left eye | |
| 228 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&left_bounds_)); | |
| 229 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
| 230 | |
| 231 // Right eye | |
| 232 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&right_bounds_)); | |
| 233 glDrawArrays(GL_TRIANGLE_FAN, 4, 4); | |
| 234 | |
| 235 glDisableVertexAttribArray(position_handle_); | |
| 236 glDisableVertexAttribArray(texcoord_handle_); | |
| 237 | |
| 238 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | |
| 239 } | |
| 240 | |
| 241 void WebVrRenderer::UpdateTextureBounds(int eye, const gvr::Rectf& bounds) { | |
| 242 if (eye == 0) { | |
| 243 left_bounds_ = bounds; | |
| 244 } else if (eye == 1) { | |
| 245 right_bounds_ = bounds; | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 WebVrRenderer::~WebVrRenderer() { | |
| 250 glDeleteBuffersARB(1, &vertex_buffer_); | |
| 251 glDeleteProgram(program_handle_); | |
| 252 } | |
| 253 | |
| 121 VrShellRenderer::VrShellRenderer() | 254 VrShellRenderer::VrShellRenderer() |
| 122 : textured_quad_renderer_(new TexturedQuadRenderer) {} | 255 : textured_quad_renderer_(new TexturedQuadRenderer), |
| 256 webvr_renderer_(new WebVrRenderer) {} | |
| 123 | 257 |
| 124 VrShellRenderer::~VrShellRenderer() {} | 258 VrShellRenderer::~VrShellRenderer() {} |
| 125 | 259 |
| 126 } // namespace vr_shell | 260 } // namespace vr_shell |
| OLD | NEW |