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_gl_util.h" | 7 #include "chrome/browser/android/vr_shell/vr_gl_util.h" |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
11 #define RECTANGULAR_TEXTURE_BUFFER(left, right, bottom, top) \ | 11 #define RECTANGULAR_TEXTURE_BUFFER(left, right, bottom, top) \ |
12 { left, bottom, left, top, right, bottom, left, top, right, top, right, \ | 12 { left, bottom, left, top, right, bottom, left, top, right, top, right, \ |
13 bottom } | 13 bottom } |
14 | 14 |
15 static constexpr float kHalfHeight = 0.5f; | 15 static constexpr float kHalfHeight = 0.5f; |
16 static constexpr float kHalfWidth = 0.5f; | 16 static constexpr float kHalfWidth = 0.5f; |
17 static constexpr float kTextureQuadPosition[18] = { | 17 static constexpr float kTextureQuadPosition[18] = { |
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 kHalfWidth, -kHalfHeight, 0.0f, kHalfWidth, kHalfHeight, 0.0f}; | 20 kHalfWidth, -kHalfHeight, 0.0f, kHalfWidth, kHalfHeight, 0.0f}; |
21 static constexpr int kPositionDataSize = 3; | 21 static constexpr int kPositionDataSize = 3; |
22 // Number of vertices passed to glDrawArrays(). | 22 // Number of vertices passed to glDrawArrays(). |
23 static constexpr int kVerticesNumber = 6; | 23 static constexpr int kVerticesNumber = 6; |
24 | 24 |
25 static constexpr float kTexturedQuadTextureCoordinates[12] = | 25 static constexpr float kTexturedQuadTextureCoordinates[12] = |
26 RECTANGULAR_TEXTURE_BUFFER(0.0f, 1.0f, 0.0f, 1.0f); | 26 RECTANGULAR_TEXTURE_BUFFER(0.0f, 1.0f, 0.0f, 1.0f); |
27 | 27 |
28 static constexpr int kTextureCoordinateDataSize = 2; | 28 static constexpr int kTextureCoordinateDataSize = 2; |
29 | 29 |
30 static constexpr float kWebVrVertices[32] = { | 30 static constexpr float kWebVrVertices[16] = { |
31 // x y u, v | 31 // x y u, v |
32 -1.f, 1.f, 0.f, 0.f, // Left Eye | 32 -1.f, 1.f, 0.f, 0.f, |
33 -1.f, -1.f, 0.f, 1.f, | 33 -1.f, -1.f, 0.f, 1.f, |
34 0.f, -1.f, 1.f, 1.f, | |
35 0.f, 1.f, 1.f, 0.f, | |
36 | |
37 0.f, 1.f, 0.f, 0.f, // Right Eye | |
38 0.f, -1.f, 0.f, 1.f, | |
39 1.f, -1.f, 1.f, 1.f, | 34 1.f, -1.f, 1.f, 1.f, |
40 1.f, 1.f, 1.f, 0.f }; | 35 1.f, 1.f, 1.f, 0.f }; |
41 static constexpr int kWebVrVerticesSize = sizeof(float) * 32; | 36 static constexpr int kWebVrVerticesSize = sizeof(float) * 16; |
42 | 37 |
43 // Reticle constants | 38 // Reticle constants |
44 static constexpr float kRingDiameter = 1.0f; | 39 static constexpr float kRingDiameter = 1.0f; |
45 static constexpr float kInnerHole = 0.0f; | 40 static constexpr float kInnerHole = 0.0f; |
46 static constexpr float kInnerRingEnd = 0.177f; | 41 static constexpr float kInnerRingEnd = 0.177f; |
47 static constexpr float kInnerRingThickness = 0.14f; | 42 static constexpr float kInnerRingThickness = 0.14f; |
48 static constexpr float kMidRingEnd = 0.177f; | 43 static constexpr float kMidRingEnd = 0.177f; |
49 static constexpr float kMidRingOpacity = 0.22f; | 44 static constexpr float kMidRingOpacity = 0.22f; |
50 static constexpr float kReticleColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; | 45 static constexpr float kReticleColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
51 | 46 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 uniform vec4 u_CopyRect; // rectangle | 91 uniform vec4 u_CopyRect; // rectangle |
97 varying vec2 v_TexCoordinate; | 92 varying vec2 v_TexCoordinate; |
98 void main() { | 93 void main() { |
99 vec2 scaledTex = | 94 vec2 scaledTex = |
100 vec2(u_CopyRect[0] + v_TexCoordinate.x * u_CopyRect[2], | 95 vec2(u_CopyRect[0] + v_TexCoordinate.x * u_CopyRect[2], |
101 u_CopyRect[1] + v_TexCoordinate.y * u_CopyRect[3]); | 96 u_CopyRect[1] + v_TexCoordinate.y * u_CopyRect[3]); |
102 gl_FragColor = texture2D(u_Texture, scaledTex); | 97 gl_FragColor = texture2D(u_Texture, scaledTex); |
103 }); | 98 }); |
104 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: | 99 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: |
105 return SHADER( | 100 return SHADER( |
106 attribute vec2 a_Position; | 101 attribute vec4 a_Position; |
107 attribute vec2 a_TexCoordinate; | |
108 uniform vec4 u_SrcRect; | |
109 varying vec2 v_TexCoordinate; | 102 varying vec2 v_TexCoordinate; |
110 | 103 |
111 void main() { | 104 void main() { |
112 v_TexCoordinate = u_SrcRect.xy + (a_TexCoordinate * u_SrcRect.zw); | 105 // Pack the texcoord into the position to avoid state changes. |
113 gl_Position = vec4(a_Position, 0.0, 1.0); | 106 v_TexCoordinate = a_Position.zw; |
| 107 gl_Position = vec4(a_Position.xy, 0.0, 1.0); |
114 }); | 108 }); |
115 case vr_shell::ShaderID::WEBVR_FRAGMENT_SHADER: | 109 case vr_shell::ShaderID::WEBVR_FRAGMENT_SHADER: |
116 return OEIE_SHADER( | 110 return OEIE_SHADER( |
117 precision highp float; | 111 precision highp float; |
118 uniform samplerExternalOES u_Texture; | 112 uniform samplerExternalOES u_Texture; |
119 varying vec2 v_TexCoordinate; | 113 varying vec2 v_TexCoordinate; |
120 | 114 |
121 void main() { | 115 void main() { |
122 gl_FragColor = texture2D(u_Texture, v_TexCoordinate); | 116 gl_FragColor = texture2D(u_Texture, v_TexCoordinate); |
123 }); | 117 }); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); | 246 glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); |
253 | 247 |
254 glDisableVertexAttribArray(position_handle_); | 248 glDisableVertexAttribArray(position_handle_); |
255 glDisableVertexAttribArray(tex_coord_handle_); | 249 glDisableVertexAttribArray(tex_coord_handle_); |
256 } | 250 } |
257 | 251 |
258 TexturedQuadRenderer::~TexturedQuadRenderer() = default; | 252 TexturedQuadRenderer::~TexturedQuadRenderer() = default; |
259 | 253 |
260 WebVrRenderer::WebVrRenderer() : | 254 WebVrRenderer::WebVrRenderer() : |
261 BaseRenderer(WEBVR_VERTEX_SHADER, WEBVR_FRAGMENT_SHADER) { | 255 BaseRenderer(WEBVR_VERTEX_SHADER, WEBVR_FRAGMENT_SHADER) { |
262 left_bounds_ = { 0.0f, 0.0f, 0.5f, 1.0f }; | |
263 right_bounds_ = { 0.5f, 0.0f, 0.5f, 1.0f }; | |
264 | |
265 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | 256 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); |
266 src_rect_uniform_handle_ = glGetUniformLocation(program_handle_, "u_SrcRect"); | |
267 | 257 |
268 // TODO(bajones): Figure out why this need to be restored. | 258 // TODO(bajones): Figure out why this need to be restored. |
269 GLint old_buffer; | 259 GLint old_buffer; |
270 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); | 260 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); |
271 | 261 |
272 glGenBuffersARB(1, &vertex_buffer_); | 262 glGenBuffersARB(1, &vertex_buffer_); |
273 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 263 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
274 glBufferData(GL_ARRAY_BUFFER, kWebVrVerticesSize, kWebVrVertices, | 264 glBufferData(GL_ARRAY_BUFFER, kWebVrVerticesSize, kWebVrVertices, |
275 GL_STATIC_DRAW); | 265 GL_STATIC_DRAW); |
276 | 266 |
277 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | 267 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); |
278 } | 268 } |
279 | 269 |
280 // Draw the stereo WebVR frame | 270 // Draw the stereo WebVR frame |
281 void WebVrRenderer::Draw(int texture_handle) { | 271 void WebVrRenderer::Draw(int texture_handle) { |
282 // TODO(bajones): Figure out why this need to be restored. | 272 // TODO(bajones): Figure out why this need to be restored. |
283 GLint old_buffer; | 273 GLint old_buffer; |
284 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); | 274 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer); |
285 | 275 |
286 glUseProgram(program_handle_); | 276 glUseProgram(program_handle_); |
287 | 277 |
288 // Bind vertex attributes | 278 // Bind vertex attributes |
289 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 279 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
290 | 280 |
291 glEnableVertexAttribArray(position_handle_); | 281 glEnableVertexAttribArray(position_handle_); |
292 glEnableVertexAttribArray(tex_coord_handle_); | |
293 | 282 |
294 glVertexAttribPointer(position_handle_, POSITION_ELEMENTS, GL_FLOAT, false, | 283 glVertexAttribPointer(position_handle_, VERTEX_ELEMENTS, GL_FLOAT, false, |
295 VERTEX_STRIDE, VOID_OFFSET(POSITION_OFFSET)); | 284 VERTEX_STRIDE, VOID_OFFSET(VERTEX_OFFSET)); |
296 glVertexAttribPointer(tex_coord_handle_, TEXCOORD_ELEMENTS, GL_FLOAT, false, | |
297 VERTEX_STRIDE, VOID_OFFSET(TEXCOORD_OFFSET)); | |
298 | 285 |
299 // Bind texture. Ideally this should be a 1:1 pixel copy. (Or even more | 286 // Bind texture. Ideally this should be a 1:1 pixel copy. (Or even more |
300 // ideally, a zero copy reuse of the texture.) For now, we're using an | 287 // ideally, a zero copy reuse of the texture.) For now, we're using an |
301 // undersized render target for WebVR, so GL_LINEAR makes it look slightly | 288 // undersized render target for WebVR, so GL_LINEAR makes it look slightly |
302 // less chunky. TODO(klausw): change this to GL_NEAREST once we're doing | 289 // less chunky. TODO(klausw): change this to GL_NEAREST once we're doing |
303 // a 1:1 copy since that should be more efficient. | 290 // a 1:1 copy since that should be more efficient. |
304 glActiveTexture(GL_TEXTURE0); | 291 glActiveTexture(GL_TEXTURE0); |
305 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle); | 292 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle); |
306 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 293 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
307 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 294 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
308 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 295 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
309 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 296 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
310 glUniform1i(tex_uniform_handle_, 0); | 297 glUniform1i(tex_uniform_handle_, 0); |
311 | 298 |
312 // TODO(bajones): Should be able handle both eyes in a single draw call. | 299 // Blit texture to buffer |
313 // Left eye | |
314 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&left_bounds_)); | |
315 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 300 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
316 | 301 |
317 // Right eye | |
318 glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&right_bounds_)); | |
319 glDrawArrays(GL_TRIANGLE_FAN, 4, 4); | |
320 | |
321 glDisableVertexAttribArray(position_handle_); | 302 glDisableVertexAttribArray(position_handle_); |
322 glDisableVertexAttribArray(tex_coord_handle_); | |
323 | 303 |
324 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); | 304 glBindBuffer(GL_ARRAY_BUFFER, old_buffer); |
325 } | 305 } |
326 | 306 |
327 void WebVrRenderer::UpdateTextureBounds(int eye, const gvr::Rectf& bounds) { | |
328 if (eye == 0) { | |
329 left_bounds_ = bounds; | |
330 } else if (eye == 1) { | |
331 right_bounds_ = bounds; | |
332 } | |
333 } | |
334 | |
335 // Note that we don't explicitly delete gl objects here, they're deleted | 307 // Note that we don't explicitly delete gl objects here, they're deleted |
336 // automatically when we call ClearGLBindings, and deleting them here leads to | 308 // automatically when we call ClearGLBindings, and deleting them here leads to |
337 // segfaults. | 309 // segfaults. |
338 WebVrRenderer::~WebVrRenderer() = default; | 310 WebVrRenderer::~WebVrRenderer() = default; |
339 | 311 |
340 ReticleRenderer::ReticleRenderer() | 312 ReticleRenderer::ReticleRenderer() |
341 : BaseRenderer(RETICLE_VERTEX_SHADER, RETICLE_FRAGMENT_SHADER) { | 313 : BaseRenderer(RETICLE_VERTEX_SHADER, RETICLE_FRAGMENT_SHADER) { |
342 combined_matrix_handle_ = | 314 combined_matrix_handle_ = |
343 glGetUniformLocation(program_handle_, "u_CombinedMatrix"); | 315 glGetUniformLocation(program_handle_, "u_CombinedMatrix"); |
344 color_handle_ = glGetUniformLocation(program_handle_, "color"); | 316 color_handle_ = glGetUniformLocation(program_handle_, "color"); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 | 420 |
449 VrShellRenderer::VrShellRenderer() | 421 VrShellRenderer::VrShellRenderer() |
450 : textured_quad_renderer_(new TexturedQuadRenderer), | 422 : textured_quad_renderer_(new TexturedQuadRenderer), |
451 webvr_renderer_(new WebVrRenderer), | 423 webvr_renderer_(new WebVrRenderer), |
452 reticle_renderer_(new ReticleRenderer), | 424 reticle_renderer_(new ReticleRenderer), |
453 laser_renderer_(new LaserRenderer) {} | 425 laser_renderer_(new LaserRenderer) {} |
454 | 426 |
455 VrShellRenderer::~VrShellRenderer() = default; | 427 VrShellRenderer::~VrShellRenderer() = default; |
456 | 428 |
457 } // namespace vr_shell | 429 } // namespace vr_shell |
OLD | NEW |