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; |
57 vertex_shader_handle_ = CompileShader( | 91 vertex_shader_handle_ = CompileShader( |
58 GL_VERTEX_SHADER, GetShaderSource(TEXTURE_QUAD_VERTEX_SHADER), error); | 92 GL_VERTEX_SHADER, GetShaderSource(TEXTURE_QUAD_VERTEX_SHADER), error); |
59 if (vertex_shader_handle_ == 0) { | 93 CHECK(vertex_shader_handle_) << error; |
60 LOG(ERROR) << error; | 94 |
61 exit(1); | |
62 } | |
63 fragment_shader_handle_ = CompileShader( | 95 fragment_shader_handle_ = CompileShader( |
64 GL_FRAGMENT_SHADER, GetShaderSource(TEXTURE_QUAD_FRAGMENT_SHADER), error); | 96 GL_FRAGMENT_SHADER, GetShaderSource(TEXTURE_QUAD_FRAGMENT_SHADER), error); |
65 if (fragment_shader_handle_ == 0) { | 97 CHECK(fragment_shader_handle_) << error; |
66 LOG(ERROR) << error; | |
67 exit(1); | |
68 } | |
69 | 98 |
70 program_handle_ = CreateAndLinkProgram( | 99 program_handle_ = CreateAndLinkProgram( |
71 vertex_shader_handle_, fragment_shader_handle_, 4, nullptr, error); | 100 vertex_shader_handle_, fragment_shader_handle_, 4, nullptr, error); |
72 if (program_handle_ == 0) { | 101 CHECK(program_handle_) << error; |
73 LOG(ERROR) << error; | 102 |
74 exit(1); | |
75 } | |
76 combined_matrix_handle_ = | 103 combined_matrix_handle_ = |
77 glGetUniformLocation(program_handle_, "u_CombinedMatrix"); | 104 glGetUniformLocation(program_handle_, "u_CombinedMatrix"); |
78 texture_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | 105 texture_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); |
79 position_handle_ = glGetAttribLocation(program_handle_, "a_Position"); | 106 position_handle_ = glGetAttribLocation(program_handle_, "a_Position"); |
80 texture_coordinate_handle_ = | 107 texture_coordinate_handle_ = |
81 glGetAttribLocation(program_handle_, "a_TexCoordinate"); | 108 glGetAttribLocation(program_handle_, "a_TexCoordinate"); |
82 } | 109 } |
83 | 110 |
84 void TexturedQuadRenderer::Draw(int texture_data_handle, | 111 void TexturedQuadRenderer::Draw(int texture_data_handle, |
85 const gvr::Mat4f& combined_matrix) { | 112 const gvr::Mat4f& combined_matrix) { |
(...skipping 25 matching lines...) Expand all Loading... |
111 | 138 |
112 glDisableVertexAttribArray(position_handle_); | 139 glDisableVertexAttribArray(position_handle_); |
113 glDisableVertexAttribArray(texture_coordinate_handle_); | 140 glDisableVertexAttribArray(texture_coordinate_handle_); |
114 } | 141 } |
115 | 142 |
116 TexturedQuadRenderer::~TexturedQuadRenderer() { | 143 TexturedQuadRenderer::~TexturedQuadRenderer() { |
117 glDeleteShader(vertex_shader_handle_); | 144 glDeleteShader(vertex_shader_handle_); |
118 glDeleteShader(fragment_shader_handle_); | 145 glDeleteShader(fragment_shader_handle_); |
119 } | 146 } |
120 | 147 |
| 148 WebVrRenderer::WebVrRenderer() { |
| 149 left_bounds_ = { 0.0f, 0.0f, 0.5f, 1.0f }; |
| 150 right_bounds_ = { 0.5f, 0.0f, 0.5f, 1.0f }; |
| 151 |
| 152 std::string error; |
| 153 GLuint vertex_shader_handle = CompileShader( |
| 154 GL_VERTEX_SHADER, GetShaderSource(WEBVR_VERTEX_SHADER), error); |
| 155 CHECK(vertex_shader_handle) << error; |
| 156 |
| 157 GLuint fragment_shader_handle = CompileShader( |
| 158 GL_FRAGMENT_SHADER, GetShaderSource(WEBVR_FRAGMENT_SHADER), error); |
| 159 CHECK(fragment_shader_handle) << error; |
| 160 |
| 161 program_handle_ = CreateAndLinkProgram( |
| 162 vertex_shader_handle, fragment_shader_handle, 2, nullptr, error); |
| 163 CHECK(program_handle_) << error; |
| 164 |
| 165 // Once the program is linked the shader objects are no longer needed |
| 166 glDeleteShader(vertex_shader_handle); |
| 167 glDeleteShader(fragment_shader_handle); |
| 168 |
| 169 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); |
| 170 src_rect_uniform_handle_ = glGetUniformLocation(program_handle_, "u_SrcRect"); |
| 171 position_handle_ = glGetAttribLocation(program_handle_, "a_Position"); |
| 172 texcoord_handle_ = glGetAttribLocation(program_handle_, "a_TexCoordinate"); |
| 173 |
| 174 // TODO(bajones): Figure out why this need to be restored. |
| 175 GLint old_buffer; |
| 176 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); |
| 177 |
| 178 glGenBuffersARB(1, &vertex_buffer_); |
| 179 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
| 180 glBufferData(GL_ARRAY_BUFFER, kWebVrVerticesSize, kWebVrVertices, |
| 181 GL_STATIC_DRAW); |
| 182 |
| 183 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); |
| 184 } |
| 185 |
| 186 // Draw the stereo WebVR frame |
| 187 void WebVrRenderer::Draw(int texture_handle) { |
| 188 // TODO(bajones): Figure out why this need to be restored. |
| 189 GLint old_buffer; |
| 190 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); |
| 191 |
| 192 glUseProgram(program_handle_); |
| 193 |
| 194 // Bind vertex attributes |
| 195 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
| 196 |
| 197 glEnableVertexAttribArray(position_handle_); |
| 198 glEnableVertexAttribArray(texcoord_handle_); |
| 199 |
| 200 glVertexAttribPointer(position_handle_, POSITION_ELEMENTS, GL_FLOAT, false, |
| 201 VERTEX_STRIDE, VOID_OFFSET(POSITION_OFFSET)); |
| 202 glVertexAttribPointer(texcoord_handle_, TEXCOORD_ELEMENTS, GL_FLOAT, false, |
| 203 VERTEX_STRIDE, VOID_OFFSET(TEXCOORD_OFFSET)); |
| 204 |
| 205 // Bind texture. |
| 206 glActiveTexture(GL_TEXTURE0); |
| 207 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle); |
| 208 glUniform1i(tex_uniform_handle_, 0); |
| 209 |
| 210 // TODO(bajones): Should be able handle both eyes in a single draw call. |
| 211 // Left eye |
| 212 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&left_bounds_)); |
| 213 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| 214 |
| 215 // Right eye |
| 216 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&right_bounds_)); |
| 217 glDrawArrays(GL_TRIANGLE_FAN, 4, 4); |
| 218 |
| 219 glDisableVertexAttribArray(position_handle_); |
| 220 glDisableVertexAttribArray(texcoord_handle_); |
| 221 |
| 222 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); |
| 223 } |
| 224 |
| 225 void WebVrRenderer::UpdateTextureBounds(int eye, const gvr::Rectf& bounds) { |
| 226 if (eye == 0) { |
| 227 left_bounds_ = bounds; |
| 228 } else if (eye == 1) { |
| 229 right_bounds_ = bounds; |
| 230 } |
| 231 } |
| 232 |
| 233 WebVrRenderer::~WebVrRenderer() { |
| 234 glDeleteBuffersARB(1, &vertex_buffer_); |
| 235 glDeleteProgram(program_handle_); |
| 236 } |
| 237 |
121 VrShellRenderer::VrShellRenderer() | 238 VrShellRenderer::VrShellRenderer() |
122 : textured_quad_renderer_(new TexturedQuadRenderer) {} | 239 : textured_quad_renderer_(new TexturedQuadRenderer), |
| 240 webvr_renderer_(new WebVrRenderer) {} |
123 | 241 |
124 VrShellRenderer::~VrShellRenderer() {} | 242 VrShellRenderer::~VrShellRenderer() {} |
125 | 243 |
126 } // namespace vr_shell | 244 } // namespace vr_shell |
OLD | NEW |