| 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 33e87fc6059a4fcb0206815df610fbed170a001f..7ed269e64b7f8b2097418c91ed04695fc2c3699a 100644
|
| --- a/chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.cc
|
| @@ -2,6 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "chrome/browser/android/vr_shell/vr_shell_icons.h"
|
| #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
|
|
|
| #include "chrome/browser/android/vr_shell/vr_gl_util.h"
|
| @@ -41,6 +42,14 @@ const float kWebVrVertices[32] = {
|
| 1.f, 1.f, 1.f, 0.f };
|
| const int kWebVrVerticesSize = sizeof(float) * 32;
|
|
|
| +const float kOverlayIconVertices[32] = {
|
| + // x y u, v
|
| + -1.f, 1.f, 0.f, 0.f,
|
| + -1.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 kOverlayIconVerticesSize = sizeof(float) * 16;
|
| +
|
| // Reticle constants
|
| static constexpr float kRingDiameter = 1.0f;
|
| static constexpr float kInnerHole = 0.0f;
|
| @@ -174,6 +183,27 @@ const char* GetShaderSource(vr_shell::ShaderID shader) {
|
| lowp vec4 final_color = color * texture_color;
|
| gl_FragColor = vec4(final_color.xyz, final_color.w * total_fade);
|
| });
|
| + case vr_shell::ShaderID::OVERLAY_ICON_VERTEX_SHADER:
|
| + return SHADER(
|
| + uniform mat4 u_CombinedMatrix;
|
| + 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 = u_CombinedMatrix * vec4(a_Position, 0.0, 1.0);
|
| + });
|
| + case vr_shell::ShaderID::OVERLAY_ICON_FRAGMENT_SHADER:
|
| + return SHADER(
|
| + precision highp float;
|
| + uniform sampler2D 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 "";
|
| @@ -439,11 +469,130 @@ void LaserRenderer::Draw(const gvr::Mat4f& combined_matrix) {
|
|
|
| LaserRenderer::~LaserRenderer() = default;
|
|
|
| +void MakeTexImage(const icon_rle_image_t& icon,
|
| + GLuint texture_data_handles[],
|
| + int icon_id) {
|
| + // Helper function to decode a bitmap from Gimp ".c file"
|
| + // run length encoded format and store it as a texture.
|
| + // TODO(klausw): remove the Gimp decoding bits once we
|
| + // can create the content from text.
|
| +
|
| + int image_pixels = icon.width * icon.height;
|
| + int image_bytes = image_pixels * icon.bytes_per_pixel;
|
| +
|
| + char* image_data = (char*)malloc(image_bytes);
|
| + if (!image_data) {
|
| + LOG(ERROR) << "Failed to allocate memory for image " << icon_id;
|
| + exit(1);
|
| + }
|
| + ICON_RUN_LENGTH_DECODE(image_data, icon.rle_pixel_data,
|
| + image_pixels, icon.bytes_per_pixel);
|
| +
|
| + glBindTexture(GL_TEXTURE_2D, texture_data_handles[icon_id]);
|
| +
|
| + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, icon.width, icon.height,
|
| + 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
| +
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| +}
|
| +
|
| +OverlayIconRenderer::OverlayIconRenderer() {
|
| + bounds_ = { 0.0f, 0.0f, 1.0f, 1.0f };
|
| +
|
| + std::string error;
|
| + GLuint vertex_shader_handle = CompileShader(
|
| + GL_VERTEX_SHADER, GetShaderSource(OVERLAY_ICON_VERTEX_SHADER), error);
|
| + CHECK(vertex_shader_handle) << error;
|
| +
|
| + GLuint fragment_shader_handle = CompileShader(
|
| + GL_FRAGMENT_SHADER, GetShaderSource(OVERLAY_ICON_FRAGMENT_SHADER), error);
|
| + CHECK(fragment_shader_handle) << error;
|
| +
|
| + program_handle_ = CreateAndLinkProgram(
|
| + vertex_shader_handle, fragment_shader_handle, 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);
|
| +
|
| + combined_matrix_handle_ =
|
| + glGetUniformLocation(program_handle_, "u_CombinedMatrix");
|
| + 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, kOverlayIconVerticesSize, kOverlayIconVertices,
|
| + GL_STATIC_DRAW);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, old_buffer);
|
| +
|
| + glGenTextures(ICON_ID_MAX, texture_data_handles_);
|
| +
|
| + MakeTexImage(icon_not_secure_small, texture_data_handles_,
|
| + ICON_INSECURE_PERMANENT);
|
| + MakeTexImage(icon_not_secure_verbose, texture_data_handles_,
|
| + ICON_INSECURE_TRANSIENT);
|
| +}
|
| +
|
| +void OverlayIconRenderer::Draw(const gvr::Mat4f& combined_matrix,
|
| + int icon_num) {
|
| + // 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_);
|
| +
|
| + // Pass in model view project matrix.
|
| + glUniformMatrix4fv(combined_matrix_handle_, 1, false,
|
| + MatrixToGLArray(combined_matrix).data());
|
| +
|
| + 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_2D, texture_data_handles_[icon_num]);
|
| + glUniform1i(tex_uniform_handle_, 0);
|
| +
|
| + glEnable(GL_BLEND);
|
| + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
| +
|
| + glUniform4fv(src_rect_uniform_handle_, 1, (float*)(&bounds_));
|
| + glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| +
|
| + glDisableVertexAttribArray(position_handle_);
|
| + glDisableVertexAttribArray(texcoord_handle_);
|
| +
|
| + glBindBuffer(GL_ARRAY_BUFFER, old_buffer);
|
| +}
|
| +
|
| +OverlayIconRenderer::~OverlayIconRenderer() = default;
|
| +
|
| VrShellRenderer::VrShellRenderer()
|
| : textured_quad_renderer_(new TexturedQuadRenderer),
|
| webvr_renderer_(new WebVrRenderer),
|
| reticle_renderer_(new ReticleRenderer),
|
| - laser_renderer_(new LaserRenderer) {}
|
| + laser_renderer_(new LaserRenderer),
|
| + overlay_icon_renderer_(new OverlayIconRenderer) {}
|
|
|
| VrShellRenderer::~VrShellRenderer() = default;
|
|
|
|
|