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 const float kWebVrVertices[32] = { | |
| 29 // x y u, v | |
| 30 -1.f, 1.f, 0.f, 0.f, // Left Eye | |
| 31 -1.f, -1.f, 0.f, 1.f, | |
| 32 0.f, -1.f, 1.f, 1.f, | |
| 33 0.f, 1.f, 1.f, 0.f, | |
| 34 | |
| 35 0.f, 1.f, 0.f, 0.f, // Right Eye | |
| 36 0.f, -1.f, 0.f, 1.f, | |
| 37 1.f, -1.f, 1.f, 1.f, | |
| 38 1.f, 1.f, 1.f, 0.f }; | |
| 39 const int kWebVrVerticesSize = sizeof(float) * 32; | |
| 40 | |
| 28 #define SHADER(Src) #Src | 41 #define SHADER(Src) #Src |
| 29 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src | 42 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src |
| 43 #define VOID_OFFSET(x) reinterpret_cast<void*>(x) | |
| 30 | 44 |
| 31 const char* GetShaderSource(ShaderID shader) { | 45 const char* GetShaderSource(ShaderID shader) { |
| 32 switch (shader) { | 46 switch (shader) { |
| 33 case TEXTURE_QUAD_VERTEX_SHADER: | 47 case TEXTURE_QUAD_VERTEX_SHADER: |
| 34 return SHADER(uniform mat4 u_CombinedMatrix; attribute vec4 a_Position; | 48 return SHADER(uniform mat4 u_CombinedMatrix; attribute vec4 a_Position; |
| 35 attribute vec2 a_TexCoordinate; | 49 attribute vec2 a_TexCoordinate; |
| 36 varying vec2 v_TexCoordinate; void main() { | 50 varying vec2 v_TexCoordinate; void main() { |
| 37 v_TexCoordinate = a_TexCoordinate; | 51 v_TexCoordinate = a_TexCoordinate; |
| 38 gl_Position = u_CombinedMatrix * a_Position; | 52 gl_Position = u_CombinedMatrix * a_Position; |
| 39 }); | 53 }); |
| 40 case TEXTURE_QUAD_FRAGMENT_SHADER: | 54 case TEXTURE_QUAD_FRAGMENT_SHADER: |
| 41 return OEIE_SHADER( | 55 return OEIE_SHADER( |
| 42 precision highp float; uniform samplerExternalOES u_Texture; | 56 precision highp float; uniform samplerExternalOES u_Texture; |
| 43 varying vec2 v_TexCoordinate; void main() { | 57 varying vec2 v_TexCoordinate; void main() { |
| 44 vec4 texture = texture2D(u_Texture, v_TexCoordinate); | 58 vec4 texture = texture2D(u_Texture, v_TexCoordinate); |
| 45 gl_FragColor = vec4(texture.r, texture.g, texture.b, 1.0); | 59 gl_FragColor = vec4(texture.r, texture.g, texture.b, 1.0); |
| 46 }); | 60 }); |
| 61 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: | |
| 62 return SHADER( | |
| 63 attribute vec2 a_Position; | |
| 64 attribute vec2 a_TexCoordinate; | |
| 65 uniform vec4 u_SrcRect; | |
| 66 varying vec2 v_TexCoordinate; | |
| 67 | |
| 68 void main() { | |
| 69 v_TexCoordinate = u_SrcRect.xy + (a_TexCoordinate * u_SrcRect.zw); | |
| 70 gl_Position = vec4(a_Position, 0.0, 1.0); | |
| 71 }); | |
| 72 case vr_shell::ShaderID::WEBVR_FRAGMENT_SHADER: | |
| 73 return OEIE_SHADER( | |
| 74 precision highp float; | |
| 75 uniform samplerExternalOES u_Texture; | |
| 76 varying vec2 v_TexCoordinate; | |
| 77 | |
| 78 void main() { | |
| 79 gl_FragColor = texture2D(u_Texture, v_TexCoordinate); | |
| 80 }); | |
| 47 default: | 81 default: |
| 48 LOG(ERROR) << "Shader source requested for unknown shader"; | 82 LOG(ERROR) << "Shader source requested for unknown shader"; |
| 49 return ""; | 83 return ""; |
| 50 } | 84 } |
| 51 } | 85 } |
| 52 | 86 |
| 53 } // namespace | 87 } // namespace |
| 54 | 88 |
| 55 TexturedQuadRenderer::TexturedQuadRenderer() { | 89 TexturedQuadRenderer::TexturedQuadRenderer() { |
| 56 std::string error; | 90 std::string error; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 | 145 |
| 112 glDisableVertexAttribArray(position_handle_); | 146 glDisableVertexAttribArray(position_handle_); |
| 113 glDisableVertexAttribArray(texture_coordinate_handle_); | 147 glDisableVertexAttribArray(texture_coordinate_handle_); |
| 114 } | 148 } |
| 115 | 149 |
| 116 TexturedQuadRenderer::~TexturedQuadRenderer() { | 150 TexturedQuadRenderer::~TexturedQuadRenderer() { |
| 117 glDeleteShader(vertex_shader_handle_); | 151 glDeleteShader(vertex_shader_handle_); |
| 118 glDeleteShader(fragment_shader_handle_); | 152 glDeleteShader(fragment_shader_handle_); |
| 119 } | 153 } |
| 120 | 154 |
| 155 WebVrRenderer::WebVrRenderer() { | |
| 156 left_bounds_ = { 0.0f, 0.0f, 0.5f, 1.0f }; | |
| 157 right_bounds_ = { 0.5f, 0.0f, 0.5f, 1.0f }; | |
| 158 | |
| 159 std::string error; | |
| 160 GLuint vertex_shader_handle = CompileShader( | |
| 161 GL_VERTEX_SHADER, GetShaderSource(WEBVR_VERTEX_SHADER), error); | |
| 162 if (vertex_shader_handle == 0) { | |
| 163 LOG(ERROR) << error; | |
| 164 exit(1); | |
|
David Trainor- moved to gerrit
2016/09/08 06:16:05
Should we just do CHECK_EQ(0, vertex_shader_handle
| |
| 165 } | |
| 166 GLuint fragment_shader_handle = CompileShader( | |
| 167 GL_FRAGMENT_SHADER, GetShaderSource(WEBVR_FRAGMENT_SHADER), error); | |
| 168 if (fragment_shader_handle == 0) { | |
| 169 LOG(ERROR) << error; | |
| 170 exit(1); | |
| 171 } | |
| 172 | |
| 173 program_handle_ = CreateAndLinkProgram( | |
| 174 vertex_shader_handle, fragment_shader_handle, 2, nullptr, error); | |
| 175 if (program_handle_ == 0) { | |
| 176 LOG(ERROR) << error; | |
| 177 exit(1); | |
| 178 } | |
| 179 | |
| 180 // Once the program is linked the shader objects are no longer needed | |
| 181 glDeleteShader(vertex_shader_handle); | |
| 182 glDeleteShader(fragment_shader_handle); | |
| 183 | |
| 184 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | |
| 185 src_rect_uniform_handle_ = glGetUniformLocation(program_handle_, "u_SrcRect"); | |
| 186 position_handle_ = glGetAttribLocation(program_handle_, "a_Position"); | |
| 187 texcoord_handle_ = glGetAttribLocation(program_handle_, "a_TexCoordinate"); | |
| 188 | |
| 189 // TODO: Figure out why this need to be restored. | |
|
David Trainor- moved to gerrit
2016/09/08 06:16:05
Add ldap?
| |
| 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, kWebVrVerticesSize, kWebVrVertices, | |
| 196 GL_STATIC_DRAW); | |
| 197 | |
| 198 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | |
| 199 } | |
| 200 | |
| 201 /** | |
| 202 * Draw the WebVR frame | |
|
David Trainor- moved to gerrit
2016/09/08 06:16:05
// instead of /*? Style guide seems to push for t
| |
| 203 */ | |
| 204 void WebVrRenderer::Draw(int texture_handle) { | |
| 205 // TODO: Figure out why this need to be restored. | |
|
David Trainor- moved to gerrit
2016/09/08 06:16:05
ldap, crbug?
| |
| 206 GLint old_buffer; | |
|
David Trainor- moved to gerrit
2016/09/08 06:16:05
A ScopedBufferRestore helper would be cool, but if
| |
| 207 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); | |
| 208 | |
| 209 glUseProgram(program_handle_); | |
| 210 | |
| 211 // Bind vertex attributes | |
| 212 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
| 213 | |
| 214 glEnableVertexAttribArray(position_handle_); | |
| 215 glEnableVertexAttribArray(texcoord_handle_); | |
| 216 | |
| 217 glVertexAttribPointer(position_handle_, POSITION_ELEMENTS, GL_FLOAT, false, | |
| 218 VERTEX_STRIDE, VOID_OFFSET(POSITION_OFFSET)); | |
| 219 glVertexAttribPointer(texcoord_handle_, TEXCOORD_ELEMENTS, GL_FLOAT, false, | |
| 220 VERTEX_STRIDE, VOID_OFFSET(TEXCOORD_OFFSET)); | |
| 221 | |
| 222 // Bind texture. | |
| 223 glActiveTexture(GL_TEXTURE0); | |
| 224 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle); | |
| 225 glUniform1i(tex_uniform_handle_, 0); | |
| 226 | |
| 227 // TODO: Should be able handle both eyes in a single draw call. | |
| 228 // Left eye | |
| 229 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&left_bounds_)); | |
| 230 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
| 231 | |
| 232 // Right eye | |
| 233 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&right_bounds_)); | |
| 234 glDrawArrays(GL_TRIANGLE_FAN, 4, 4); | |
| 235 | |
| 236 glDisableVertexAttribArray(position_handle_); | |
| 237 glDisableVertexAttribArray(texcoord_handle_); | |
| 238 | |
| 239 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | |
| 240 } | |
| 241 | |
| 242 void WebVrRenderer::UpdateTextureBounds(int eye, const gvr::Rectf& bounds) { | |
| 243 if (eye == 0) { | |
| 244 left_bounds_ = bounds; | |
| 245 } else if (eye == 1) { | |
| 246 right_bounds_ = bounds; | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 WebVrRenderer::~WebVrRenderer() { | |
| 251 glDeleteBuffersARB(1, &vertex_buffer_); | |
| 252 glDeleteProgram(program_handle_); | |
| 253 } | |
| 254 | |
| 121 VrShellRenderer::VrShellRenderer() | 255 VrShellRenderer::VrShellRenderer() |
| 122 : textured_quad_renderer_(new TexturedQuadRenderer) {} | 256 : textured_quad_renderer_(new TexturedQuadRenderer), |
| 257 webvr_renderer_(new WebVrRenderer) {} | |
| 123 | 258 |
| 124 VrShellRenderer::~VrShellRenderer() {} | 259 VrShellRenderer::~VrShellRenderer() {} |
| 125 | 260 |
| 126 } // namespace vr_shell | 261 } // namespace vr_shell |
| OLD | NEW |