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