| Index: chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| diff --git a/chrome/browser/android/vr_shell/vr_shell_renderer.cc b/chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| index 7fb405fdd5b3717c19ce424240913e5adc7455bb..6f21d120f66a6b7e2127fc2ce763a7c49e844745 100644
|
| --- a/chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| @@ -25,8 +25,22 @@ const float kTexturedQuadTextureCoordinates[12] = {
|
| 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f};
|
| const int kTextureCoordinateDataSize = 2;
|
|
|
| +const float kWebVrVertices[32] = {
|
| + // x y u, v
|
| + -1.f, 1.f, 0.f, 0.f, // Left Eye
|
| + -1.f, -1.f, 0.f, 1.f,
|
| + 0.f, -1.f, 1.f, 1.f,
|
| + 0.f, 1.f, 1.f, 0.f,
|
| +
|
| + 0.f, 1.f, 0.f, 0.f, // Right Eye
|
| + 0.f, -1.f, 0.f, 1.f,
|
| + 1.f, -1.f, 1.f, 1.f,
|
| + 1.f, 1.f, 1.f, 0.f };
|
| +const int kWebVrVerticesSize = sizeof(float) * 32;
|
| +
|
| #define SHADER(Src) #Src
|
| #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src
|
| +#define VOID_OFFSET(x) reinterpret_cast<void*>(x)
|
|
|
| const char* GetShaderSource(ShaderID shader) {
|
| switch (shader) {
|
| @@ -44,6 +58,26 @@ const char* GetShaderSource(ShaderID shader) {
|
| vec4 texture = texture2D(u_Texture, v_TexCoordinate);
|
| gl_FragColor = vec4(texture.r, texture.g, texture.b, 1.0);
|
| });
|
| + case vr_shell::ShaderID::WEBVR_VERTEX_SHADER:
|
| + return SHADER(
|
| + attribute vec2 a_Position;
|
| + attribute vec2 a_TexCoordinate;
|
| + uniform vec4 u_SrcRect;
|
| + varying vec2 v_TexCoordinate;
|
| +
|
| + void main() {
|
| + v_TexCoordinate = u_SrcRect.xy + (a_TexCoordinate * u_SrcRect.zw);
|
| + gl_Position = vec4(a_Position, 0.0, 1.0);
|
| + });
|
| + case vr_shell::ShaderID::WEBVR_FRAGMENT_SHADER:
|
| + return OEIE_SHADER(
|
| + precision highp float;
|
| + uniform samplerExternalOES u_Texture;
|
| + varying vec2 v_TexCoordinate;
|
| +
|
| + void main() {
|
| + gl_FragColor = texture2D(u_Texture, v_TexCoordinate);
|
| + });
|
| default:
|
| LOG(ERROR) << "Shader source requested for unknown shader";
|
| return "";
|
| @@ -56,23 +90,16 @@ TexturedQuadRenderer::TexturedQuadRenderer() {
|
| std::string error;
|
| vertex_shader_handle_ = CompileShader(
|
| GL_VERTEX_SHADER, GetShaderSource(TEXTURE_QUAD_VERTEX_SHADER), error);
|
| - if (vertex_shader_handle_ == 0) {
|
| - LOG(ERROR) << error;
|
| - exit(1);
|
| - }
|
| + CHECK(vertex_shader_handle_) << error;
|
| +
|
| fragment_shader_handle_ = CompileShader(
|
| GL_FRAGMENT_SHADER, GetShaderSource(TEXTURE_QUAD_FRAGMENT_SHADER), error);
|
| - if (fragment_shader_handle_ == 0) {
|
| - LOG(ERROR) << error;
|
| - exit(1);
|
| - }
|
| + CHECK(fragment_shader_handle_) << error;
|
|
|
| program_handle_ = CreateAndLinkProgram(
|
| vertex_shader_handle_, fragment_shader_handle_, 4, nullptr, error);
|
| - if (program_handle_ == 0) {
|
| - LOG(ERROR) << error;
|
| - exit(1);
|
| - }
|
| + CHECK(program_handle_) << error;
|
| +
|
| combined_matrix_handle_ =
|
| glGetUniformLocation(program_handle_, "u_CombinedMatrix");
|
| texture_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture");
|
| @@ -118,8 +145,99 @@ TexturedQuadRenderer::~TexturedQuadRenderer() {
|
| glDeleteShader(fragment_shader_handle_);
|
| }
|
|
|
| +WebVrRenderer::WebVrRenderer() {
|
| + left_bounds_ = { 0.0f, 0.0f, 0.5f, 1.0f };
|
| + right_bounds_ = { 0.5f, 0.0f, 0.5f, 1.0f };
|
| +
|
| + std::string error;
|
| + GLuint vertex_shader_handle = CompileShader(
|
| + GL_VERTEX_SHADER, GetShaderSource(WEBVR_VERTEX_SHADER), error);
|
| + CHECK(vertex_shader_handle) << error;
|
| +
|
| + GLuint fragment_shader_handle = CompileShader(
|
| + GL_FRAGMENT_SHADER, GetShaderSource(WEBVR_FRAGMENT_SHADER), error);
|
| + CHECK(fragment_shader_handle) << error;
|
| +
|
| + program_handle_ = CreateAndLinkProgram(
|
| + vertex_shader_handle, fragment_shader_handle, 2, nullptr, error);
|
| + CHECK(program_handle_) << error;
|
| +
|
| + // Once the program is linked the shader objects are no longer needed
|
| + glDeleteShader(vertex_shader_handle);
|
| + glDeleteShader(fragment_shader_handle);
|
| +
|
| + tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture");
|
| + src_rect_uniform_handle_ = glGetUniformLocation(program_handle_, "u_SrcRect");
|
| + position_handle_ = glGetAttribLocation(program_handle_, "a_Position");
|
| + texcoord_handle_ = glGetAttribLocation(program_handle_, "a_TexCoordinate");
|
| +
|
| + // TODO(bajones): Figure out why this need to be restored.
|
| + GLint old_buffer;
|
| + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer);
|
| +
|
| + glGenBuffersARB(1, &vertex_buffer_);
|
| + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
|
| + glBufferData(GL_ARRAY_BUFFER, kWebVrVerticesSize, kWebVrVertices,
|
| + GL_STATIC_DRAW);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, old_buffer);
|
| +}
|
| +
|
| +// Draw the stereo WebVR frame
|
| +void WebVrRenderer::Draw(int texture_handle) {
|
| + // TODO(bajones): Figure out why this need to be restored.
|
| + GLint old_buffer;
|
| + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &old_buffer);
|
| +
|
| + glUseProgram(program_handle_);
|
| +
|
| + // Bind vertex attributes
|
| + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
|
| +
|
| + glEnableVertexAttribArray(position_handle_);
|
| + glEnableVertexAttribArray(texcoord_handle_);
|
| +
|
| + glVertexAttribPointer(position_handle_, POSITION_ELEMENTS, GL_FLOAT, false,
|
| + VERTEX_STRIDE, VOID_OFFSET(POSITION_OFFSET));
|
| + glVertexAttribPointer(texcoord_handle_, TEXCOORD_ELEMENTS, GL_FLOAT, false,
|
| + VERTEX_STRIDE, VOID_OFFSET(TEXCOORD_OFFSET));
|
| +
|
| + // Bind texture.
|
| + glActiveTexture(GL_TEXTURE0);
|
| + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_handle);
|
| + glUniform1i(tex_uniform_handle_, 0);
|
| +
|
| + // TODO(bajones): Should be able handle both eyes in a single draw call.
|
| + // Left eye
|
| + glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&left_bounds_));
|
| + glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| +
|
| + // Right eye
|
| + glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&right_bounds_));
|
| + glDrawArrays(GL_TRIANGLE_FAN, 4, 4);
|
| +
|
| + glDisableVertexAttribArray(position_handle_);
|
| + glDisableVertexAttribArray(texcoord_handle_);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, old_buffer);
|
| +}
|
| +
|
| +void WebVrRenderer::UpdateTextureBounds(int eye, const gvr::Rectf& bounds) {
|
| + if (eye == 0) {
|
| + left_bounds_ = bounds;
|
| + } else if (eye == 1) {
|
| + right_bounds_ = bounds;
|
| + }
|
| +}
|
| +
|
| +WebVrRenderer::~WebVrRenderer() {
|
| + glDeleteBuffersARB(1, &vertex_buffer_);
|
| + glDeleteProgram(program_handle_);
|
| +}
|
| +
|
| VrShellRenderer::VrShellRenderer()
|
| - : textured_quad_renderer_(new TexturedQuadRenderer) {}
|
| + : textured_quad_renderer_(new TexturedQuadRenderer),
|
| + webvr_renderer_(new WebVrRenderer) {}
|
|
|
| VrShellRenderer::~VrShellRenderer() {}
|
|
|
|
|