OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Native.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2015-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include <jni.h>
22 #include <android/log.h>
23 
24 #include <GLES3/gl3.h>
25 #include <EGL/egl.h>
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <cstring>
31 
32 #include "Matrix.h"
33 
34 #define LOG_TAG "libNative"
35 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
36 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
37 
38 #define GL_CHECK(x) \
39  x; \
40  { \
41  GLenum glError = glGetError(); \
42  if(glError != GL_NO_ERROR) { \
43  LOGE("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
44  exit(1); \
45  } \
46  }
47 
48 using namespace MaliSDK;
49 
57 
63 
70 
76 float angle = 0;
77 
78 typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);
80 
81 /* Multiview vertexShader */
82 static const char multiviewVertexShader[] =
83  "#version 300 es\n"
84  "#extension GL_OVR_multiview : enable\n"
85 
86  "layout(num_views = 4) in;\n"
87 
88  "in vec3 vertexPosition;\n"
89  "in vec3 vertexNormal;\n"
90  "uniform mat4 modelViewProjection[4];\n"
91  "uniform mat4 model;\n"
92  "out vec3 v_normal;\n"
93 
94  "void main()\n"
95  "{\n"
96  " gl_Position = modelViewProjection[gl_ViewID_OVR] * vec4(vertexPosition, 1.0);\n"
97  " v_normal = (model * vec4(vertexNormal, 0.0f)).xyz;\n"
98  "}\n";
99 
100 /* Multiview fragmentShader */
101 static const char multiviewFragmentShader[] =
102  "#version 300 es\n"
103  "precision highp float;\n"
104 
105  "in vec3 v_normal;\n"
106  "out vec4 f_color;\n"
107 
108  "vec3 light(vec3 n, vec3 l, vec3 c)\n"
109  "{\n"
110  " float ndotl = max(dot(n, l), 0.0);\n"
111  " return ndotl * c;\n"
112  "}\n"
113 
114  "void main()\n"
115  "{\n"
116  " vec3 albedo = vec3(0.95, 0.84, 0.62);\n"
117  " vec3 n = normalize(v_normal);\n"
118  " f_color.rgb = vec3(0.0);\n"
119  " f_color.rgb += light(n, normalize(vec3(1.0)), vec3(1.0));\n"
120  " f_color.rgb += light(n, normalize(vec3(-1.0, -1.0, 0.0)), vec3(0.2, 0.23, 0.35));\n"
121 
122  " f_color.a = 1.0;\n"
123  "}\n";
124 
125 /* Textured quad vertexShader */
126 static const char texturedQuadVertexShader[] =
127  "#version 300 es\n"
128  "in vec3 attributePosition;\n"
129  "in vec2 attributeLowResTexCoord;\n"
130  "in vec2 attributeHighResTexCoord;\n"
131  "out vec2 vLowResTexCoord;\n"
132  "out vec2 vHighResTexCoord;\n"
133  "void main()\n"
134  "{\n"
135  " vLowResTexCoord = attributeLowResTexCoord;\n"
136  " vHighResTexCoord = attributeHighResTexCoord;\n"
137  " gl_Position = vec4(attributePosition, 1.0);\n"
138  "}\n";
139 
140 /* Textured quad fragmentShader */
141 static const char texturedQuadFragmentShader[] =
142  "#version 300 es\n"
143  "precision mediump float;\n"
144  "precision mediump int;\n"
145  "precision mediump sampler2DArray;\n"
146  "in vec2 vLowResTexCoord;\n"
147  "in vec2 vHighResTexCoord;\n"
148  "out vec4 fragColor;\n"
149  "uniform sampler2DArray tex;\n"
150  "uniform int layerIndex;\n"
151  "void main()\n"
152  "{\n"
153  " vec4 lowResSample = texture(tex, vec3(vLowResTexCoord, layerIndex));\n"
154  " vec4 highResSample = texture(tex, vec3(vHighResTexCoord, layerIndex + 2));\n"
155  " // Using squared distance to middle of screen for interpolating.\n"
156  " vec2 distVec = vec2(0.5) - vHighResTexCoord;\n"
157  " float squaredDist = dot(distVec, distVec);\n"
158  " // Using the high res texture when distance from center is less than 0.5 in texture coordinates (0.25 is 0.5 squared).\n"
159  " // When the distance is less than 0.2 (0.04 is 0.2 squared), only the high res texture will be used.\n"
160  " float lerpVal = smoothstep(-0.25, -0.04, -squaredDist);\n"
161  " fragColor = mix(lowResSample, highResSample, lerpVal);\n"
162  "}\n";
163 
164 /* Vertices for cube drawn with multiview. */
166 { //Front face
167  -1.0f, -1.0f, -1.0f,
168  1.0f, -1.0f, -1.0f,
169  1.0f, 1.0f, -1.0f,
170  -1.0f, 1.0f, -1.0f,
171 
172  // Right face
173  1.0f, -1.0f, -1.0f,
174  1.0f, -1.0f, 1.0f,
175  1.0f, 1.0f, 1.0f,
176  1.0f, 1.0f, -1.0f,
177 
178  // Back face
179  1.0f, -1.0f, 1.0f,
180  -1.0f, -1.0f, 1.0f,
181  -1.0f, 1.0f, 1.0f,
182  1.0f, 1.0f, 1.0f,
183 
184  // Left face
185  -1.0f, -1.0f, 1.0f,
186  -1.0f, -1.0f, -1.0f,
187  -1.0f, 1.0f, -1.0f,
188  -1.0f, 1.0f, 1.0f,
189 
190  // Top face
191  -1.0f, 1.0f, -1.0f,
192  1.0f, 1.0f, -1.0f,
193  1.0f, 1.0f, 1.0f,
194  -1.0f, 1.0f, 1.0f,
195 
196  // Bottom face
197  1.0f, -1.0f, 1.0f,
198  -1.0f, -1.0f, 1.0f,
199  -1.0f, -1.0f, -1.0f,
200  1.0f, -1.0f, -1.0f
201 };
202 
203 /* Normals for cube drawn with multiview. */
205 {
206  //Front face
207  0.0f, 0.0f, 1.0f,
208  0.0f, 0.0f, 1.0f,
209  0.0f, 0.0f, 1.0f,
210  0.0f, 0.0f, 1.0f,
211 
212  // Right face
213  1.0f, 0.0f, 0.0f,
214  1.0f, 0.0f, 0.0f,
215  1.0f, 0.0f, 0.0f,
216  1.0f, 0.0f, 0.0f,
217 
218  // Back face
219  0.0f, 0.0f, -1.0f,
220  0.0f, 0.0f, -1.0f,
221  0.0f, 0.0f, -1.0f,
222  0.0f, 0.0f, -1.0f,
223 
224  // Left face
225  -1.0f, 0.0f, 0.0f,
226  -1.0f, 0.0f, 0.0f,
227  -1.0f, 0.0f, 0.0f,
228  -1.0f, 0.0f, 0.0f,
229 
230  // Top face
231  0.0f, 1.0f, 0.0f,
232  0.0f, 1.0f, 0.0f,
233  0.0f, 1.0f, 0.0f,
234  0.0f, 1.0f, 0.0f,
235 
236  // Bottom face
237  0.0f, -1.0f, 0.0f,
238  0.0f, -1.0f, 0.0f,
239  0.0f, -1.0f, 0.0f,
240  0.0f, -1.0f, 0.0f
241 };
242 
243 /* Indices for cube drawn with multiview. */
244 GLushort multiviewIndices[] =
245 {
246  //Front face
247  0, 1, 2,
248  0, 2, 3,
249 
250  // Right face
251  4, 5, 6,
252  4, 6, 7,
253 
254  // Back face
255  8, 9, 10,
256  8, 10, 11,
257 
258  // Left face
259  12, 13, 14,
260  12, 14, 15,
261 
262  // Top face
263  16, 17, 18,
264  16, 18, 19,
265 
266  // Bottom face
267  20, 21, 22,
268  20, 22, 23
269 };
270 
271 /* Textured quad geometry */
273 {
274  -1.0f, -1.0f, 0.0f,
275  1.0f, -1.0f, 0.0f,
276  1.0f, 1.0f, 0.0f,
277 
278  -1.0f, -1.0f, 0.0f,
279  1.0f, 1.0f, 0.0f,
280  -1.0f, 1.0f, 0.0f
281 };
282 
283 /* Textured quad low resolution texture coordinates */
285 {
286  0, 0,
287  1, 0,
288  1, 1,
289 
290  0, 0,
291  1, 1,
292  0, 1
293 };
294 
295 /* Textured quad high resolution texture coordinates */
297 {
298  -0.5, -0.5,
299  1.5, -0.5,
300  1.5, 1.5,
301 
302  -0.5, -0.5,
303  1.5, 1.5,
304  -0.5, 1.5
305 };
306 
307 GLuint loadShader(GLenum shaderType, const char* shaderSource)
308 {
309  GLuint shader = GL_CHECK(glCreateShader(shaderType));
310  if (shader != 0)
311  {
312  GL_CHECK(glShaderSource(shader, 1, &shaderSource, NULL));
313  GL_CHECK(glCompileShader(shader));
314  GLint compiled = 0;
315  GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
316  if (compiled != GL_TRUE)
317  {
318  GLint infoLen = 0;
319  GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen));
320 
321  if (infoLen > 0)
322  {
323  char * logBuffer = (char*) malloc(infoLen);
324 
325  if (logBuffer != NULL)
326  {
327  GL_CHECK(glGetShaderInfoLog(shader, infoLen, NULL, logBuffer));
328  LOGE("Could not Compile Shader %d:\n%s\n", shaderType, logBuffer);
329  free(logBuffer);
330  logBuffer = NULL;
331  }
332 
333  GL_CHECK(glDeleteShader(shader));
334  shader = 0;
335  }
336  }
337  }
338 
339  return shader;
340 }
341 
342 GLuint createProgram(const char* vertexSource, const char * fragmentSource)
343 {
344  GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
345  if (vertexShader == 0)
346  {
347  return 0;
348  }
349 
350  GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
351  if (fragmentShader == 0)
352  {
353  return 0;
354  }
355 
356  GLuint program = GL_CHECK(glCreateProgram());
357 
358  if (program != 0)
359  {
360  GL_CHECK(glAttachShader(program, vertexShader));
361  GL_CHECK(glAttachShader(program, fragmentShader));
362  GL_CHECK(glLinkProgram(program));
363  GLint linkStatus = GL_FALSE;
364  GL_CHECK(glGetProgramiv(program, GL_LINK_STATUS, &linkStatus));
365  if(linkStatus != GL_TRUE)
366  {
367  GLint bufLength = 0;
368  GL_CHECK(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength));
369  if (bufLength > 0)
370  {
371  char* logBuffer = (char*) malloc(bufLength);
372 
373  if (logBuffer != NULL)
374  {
375  GL_CHECK(glGetProgramInfoLog(program, bufLength, NULL, logBuffer));
376  LOGE("Could not link program:\n%s\n", logBuffer);
377  free(logBuffer);
378  logBuffer = NULL;
379  }
380  }
381  GL_CHECK(glDeleteProgram(program));
382  program = 0;
383  }
384  }
385  return program;
386 }
387 
388 bool setupFBO(int width, int height)
389 {
390  // Create array texture
391  GL_CHECK(glGenTextures(1, &frameBufferTextureId));
393  GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
394  GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
395  GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, 4));
396 
397  /* Initialize FBO. */
398  GL_CHECK(glGenFramebuffers(1, &frameBufferObjectId));
399 
400  /* Bind our framebuffer for rendering. */
401  GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferObjectId));
402 
403  /* Attach texture to the framebuffer. */
404  GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
405  frameBufferTextureId, 0, 0, 4));
406 
407  /* Create array depth texture */
408  GL_CHECK(glGenTextures(1, &frameBufferDepthTextureId));
410  GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT24, width, height, 4));
411 
412  /* Attach depth texture to the framebuffer. */
413  GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
414  frameBufferDepthTextureId, 0, 0, 4));
415 
416  /* Check FBO is OK. */
417  GLenum result = GL_CHECK(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
418  if (result != GL_FRAMEBUFFER_COMPLETE)
419  {
420  LOGE("Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__);
421  /* Unbind framebuffer. */
422  GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
423  return false;
424  }
425  return true;
426 }
427 
428 bool setupGraphics(int width, int height)
429 {
430  /*
431  * Make sure the required multiview extension is present.
432  */
433  const GLubyte* extensions = GL_CHECK(glGetString(GL_EXTENSIONS));
434  const char *found_extension = strstr((const char*)extensions, "GL_OVR_multiview");
435  if (NULL == found_extension)
436  {
437  LOGI("OpenGL ES 3.0 implementation does not support GL_OVR_multiview extension.\n");
438  exit(EXIT_FAILURE);
439  }
440  else
441  {
443  (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)eglGetProcAddress ("glFramebufferTextureMultiviewOVR");
445  {
446  LOGI("Can not get proc address for glFramebufferTextureMultiviewOVR.\n");
447  exit(EXIT_FAILURE);
448  }
449  }
450 
451  /* Enable culling and depth testing. */
452  GL_CHECK(glDisable(GL_CULL_FACE));
453  GL_CHECK(glEnable(GL_DEPTH_TEST));
454  GL_CHECK(glDepthFunc(GL_LEQUAL));
455 
456  /* Setting screen width and height for use when rendering. */
457  screenWidth = width;
459 
460  if (!setupFBO(fboWidth, fboHeight))
461  {
462  LOGE ("Could not create multiview FBO");
463  return false;
464  }
465 
466  /* Creating program for drawing textured quad. */
468  if (texturedQuadProgram == 0)
469  {
470  LOGE ("Could not create textured quad program");
471  return false;
472  }
473 
474  /* Get attribute and uniform locations for textured quad program. */
475  texturedQuadVertexLocation = GL_CHECK(glGetAttribLocation(texturedQuadProgram, "attributePosition"));
476  texturedQuadLowResTexCoordLocation = GL_CHECK(glGetAttribLocation(texturedQuadProgram, "attributeLowResTexCoord"));
477  texturedQuadHighResTexCoordLocation = GL_CHECK(glGetAttribLocation(texturedQuadProgram, "attributeHighResTexCoord"));
478  texturedQuadSamplerLocation = GL_CHECK(glGetUniformLocation(texturedQuadProgram, "tex"));
479  texturedQuadLayerIndexLocation = GL_CHECK(glGetUniformLocation(texturedQuadProgram, "layerIndex"));
480 
481  /* Creating program for drawing object with multiview. */
483  if (multiviewProgram == 0)
484  {
485  LOGE ("Could not create multiview program");
486  return false;
487  }
488 
489  /* Get attribute and uniform locations for multiview program. */
490  multiviewVertexLocation = GL_CHECK(glGetAttribLocation(multiviewProgram, "vertexPosition"));
491  multiviewVertexNormalLocation = GL_CHECK(glGetAttribLocation(multiviewProgram, "vertexNormal"));
492  multiviewModelViewProjectionLocation = GL_CHECK(glGetUniformLocation(multiviewProgram, "modelViewProjection"));
493  multiviewModelLocation = GL_CHECK(glGetUniformLocation(multiviewProgram, "model"));
494 
495  /*
496  * Set up the perspective matrices for each view. Rendering is done twice in each eye position with different
497  * field of view. The narrower field of view should give half the size for the near plane in order to
498  * render the center of the scene at a higher resolution. The resulting high resolution and low resolution
499  * images will later be interpolated to create an image with higher resolution in the center of the screen
500  * than on the outer parts of the screen.
501  * 1.5707963268 rad = 90 degrees.
502  * 0.9272952188 rad = 53.1301024 degrees. This angle gives half the size for the near plane.
503  */
504  projectionMatrix[0] = Matrix::matrixPerspective(1.5707963268f, (float)width / (float)height, 0.1f, 100.0f);
505  projectionMatrix[1] = Matrix::matrixPerspective(1.5707963268f, (float)width / (float)height, 0.1f, 100.0f);
506  projectionMatrix[2] = Matrix::matrixPerspective(0.9272952188f, (float)width / (float)height, 0.1f, 100.0f);
507  projectionMatrix[3] = Matrix::matrixPerspective(0.9272952188f, (float)width / (float)height, 0.1f, 100.0f);
508 
509  GL_CHECK(glViewport(0, 0, width, height));
510 
511  /* Setting up model view matrices for each of the */
512  Vec3f leftCameraPos = {-0.5f, 0.0f, 5.0f};
513  Vec3f rightCameraPos = {0.5f, 0.0f, 5.0f};
514  Vec3f lookAt = {0.0f, 0.0f, 0.0f};
515  Vec3f upVec = {0.0f, 1.0f, 0.0f};
516  viewMatrix[0] = Matrix::matrixCameraLookAt(leftCameraPos, lookAt, upVec);
517  viewMatrix[1] = Matrix::matrixCameraLookAt(rightCameraPos, lookAt, upVec);
518  viewMatrix[2] = Matrix::matrixCameraLookAt(leftCameraPos, lookAt, upVec);
519  viewMatrix[3] = Matrix::matrixCameraLookAt(rightCameraPos, lookAt, upVec);
520 
522  viewProjectionMatrix[1] = projectionMatrix[1] * viewMatrix[1];
523  viewProjectionMatrix[2] = projectionMatrix[2] * viewMatrix[2];
524  viewProjectionMatrix[3] = projectionMatrix[3] * viewMatrix[3];
525 
526  return true;
527 }
528 
529 void renderToFBO(int width, int height)
530 {
531  /* Rendering to FBO. */
532  GL_CHECK(glViewport(0, 0, width, height));
533 
534  /* Bind our framebuffer for rendering. */
535  GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObjectId));
536 
537  GL_CHECK(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
538 
539  /* Rotating the cube. */
545 
546  GL_CHECK(glUseProgram(multiviewProgram));
547 
548  /* Upload vertex attributes. */
549  GL_CHECK(glVertexAttribPointer(multiviewVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, multiviewVertices));
550  GL_CHECK(glEnableVertexAttribArray(multiviewVertexLocation));
551  GL_CHECK(glVertexAttribPointer(multiviewVertexNormalLocation, 3, GL_FLOAT, GL_FALSE, 0, multiviewNormals));
552  GL_CHECK(glEnableVertexAttribArray(multiviewVertexNormalLocation));
553 
554  /* Upload model view projection matrices. */
555 
556  GL_CHECK(glUniformMatrix4fv(multiviewModelViewProjectionLocation, 4, GL_FALSE, modelViewProjectionMatrix[0].getAsArray()));
557  GL_CHECK(glUniformMatrix4fv(multiviewModelLocation, 1, GL_FALSE, modelMatrix.getAsArray()));
558 
559  /* Draw a cube. */
560  GL_CHECK(glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, multiviewIndices));
561 
562  /* Draw a translated cube. */
563  Matrix translatedModelMatrix = Matrix::createTranslation(-3.5, 0.0, 0.0) * modelMatrix;
564  modelViewProjectionMatrix[0] = viewProjectionMatrix[0] * translatedModelMatrix;
565  modelViewProjectionMatrix[1] = viewProjectionMatrix[1] * translatedModelMatrix;
566  modelViewProjectionMatrix[2] = viewProjectionMatrix[2] * translatedModelMatrix;
567  modelViewProjectionMatrix[3] = viewProjectionMatrix[3] * translatedModelMatrix;
568  GL_CHECK(glUniformMatrix4fv(multiviewModelViewProjectionLocation, 4, GL_FALSE, modelViewProjectionMatrix[0].getAsArray()));
569  GL_CHECK(glUniformMatrix4fv(multiviewModelLocation, 1, GL_FALSE, translatedModelMatrix.getAsArray()));
570  GL_CHECK(glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, multiviewIndices));
571 
572  /* Draw another translated cube. */
573  translatedModelMatrix = Matrix::createTranslation(3.5, 0.0, 0.0) * modelMatrix;
574  modelViewProjectionMatrix[0] = viewProjectionMatrix[0] * translatedModelMatrix;
575  modelViewProjectionMatrix[1] = viewProjectionMatrix[1] * translatedModelMatrix;
576  modelViewProjectionMatrix[2] = viewProjectionMatrix[2] * translatedModelMatrix;
577  modelViewProjectionMatrix[3] = viewProjectionMatrix[3] * translatedModelMatrix;
578  GL_CHECK(glUniformMatrix4fv(multiviewModelViewProjectionLocation, 4, GL_FALSE, modelViewProjectionMatrix[0].getAsArray()));
579  GL_CHECK(glUniformMatrix4fv(multiviewModelLocation, 1, GL_FALSE, translatedModelMatrix.getAsArray()));
580  GL_CHECK(glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, multiviewIndices));
581 
582  angle += 1;
583  if (angle > 360)
584  {
585  angle -= 360;
586  }
587 
588  /* Go back to the backbuffer for rendering to the screen. */
589  GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
590 }
591 
593 {
594  /*
595  * Render the scene to the multiview texture. This will render to 4 different layers of the texture,
596  * using different projection and view matrices for each layer.
597  */
599 
600  GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
601  GL_CHECK(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
602 
603  /*
604  * Render the multiview texture layers to separate viewports. Each viewport corresponds to one eye,
605  * and will use two different texture layers from the multiview texture, one with a wide field of view
606  * and one with a narrow field of view.
607  */
608  for (int i = 0; i < 2; i++)
609  {
610  glViewport(i * screenWidth/2, 0, screenWidth/2, screenHeight);
611 
612  /* Use the texture array that was drawn to using multiview. */
613  GL_CHECK(glActiveTexture(GL_TEXTURE0));
615 
616  GL_CHECK(glUseProgram(texturedQuadProgram));
617 
618  /* Upload vertex attributes. */
619  GL_CHECK(glVertexAttribPointer(texturedQuadVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, texturedQuadCoordinates));
620  GL_CHECK(glEnableVertexAttribArray(texturedQuadVertexLocation));
621  GL_CHECK(glVertexAttribPointer(texturedQuadLowResTexCoordLocation, 2, GL_FLOAT,
622  GL_FALSE, 0, texturedQuadLowResTexCoordinates));
623  GL_CHECK(glEnableVertexAttribArray(texturedQuadLowResTexCoordLocation));
624  GL_CHECK(glVertexAttribPointer(texturedQuadHighResTexCoordLocation, 2, GL_FLOAT,
625  GL_FALSE, 0, texturedQuadHighResTexCoordinates));
626  GL_CHECK(glEnableVertexAttribArray(texturedQuadHighResTexCoordLocation));
627 
628  /*
629  * Upload uniforms. The layerIndex is used to choose what layer of the array texture to sample from.
630  * The shader will use the given layerIndex and layerIndex + 2, where layerIndex gives the layer with
631  * the wide field of view, where the entire scene has been rendered, and layerIndex + 2 gives the layer
632  * with the narrow field of view, where only the center of the scene has been rendered.
633  */
634  GL_CHECK(glUniform1i(texturedQuadSamplerLocation, 0));
635  GL_CHECK(glUniform1i(texturedQuadLayerIndexLocation, i));
636 
637  /* Draw textured quad using the multiview texture. */
638  GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 6));
639  }
640 }
641 
642 extern "C"
643 {
645  JNIEnv * env, jobject obj, jint width, jint height);
647  JNIEnv * env, jobject obj);
648 };
649 
651  JNIEnv * env, jobject obj, jint width, jint height)
652 {
653  setupGraphics(width, height);
654 }
655 
657  JNIEnv * env, jobject obj)
658 {
659  renderFrame();
660 }
void setupGraphics(int width, int height)
Definition: Native.cpp:1256
float texturedQuadLowResTexCoordinates[]
Definition: Native.cpp:235
GLuint texturedQuadLowResTexCoordLocation
Definition: Native.cpp:124
GLuint screenWidth
Definition: Native.cpp:77
void renderToFBO(const int width, const int height, const GLuint frameBufferID)
Definition: Native.cpp:729
float projectionMatrix[16]
Definition: Native.cpp:156
GLuint multiviewVertexLocation
Definition: Native.cpp:99
#define GL_CHECK(x)
Definition: Native.cpp:38
Matrix modelViewProjectionMatrix[VIEWS]
Definition: Native.cpp:141
GLuint texturedQuadVertexLocation
Definition: Native.cpp:123
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLuint texturedQuadProgram
Definition: Native.cpp:122
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_multiview_NativeLibrary_init(JNIEnv *env, jobject obj, jint width, jint height)
Definition: Native.cpp:650
Matrix modelMatrix
Definition: Native.cpp:142
Functions for manipulating matrices.
Definition: Matrix.h:31
GLfloat multiviewVertices[]
Definition: Native.cpp:165
void(* PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei)
Definition: Native.cpp:158
static Matrix createTranslation(float x, float y, float z)
Create and return a translation matrix.
Definition: Matrix.cpp:414
static const char texturedQuadVertexShader[]
Definition: Native.cpp:126
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
Definition: Matrix.cpp:425
static const char multiviewVertexShader[]
Definition: Native.cpp:82
float angle
Definition: Native.cpp:158
static const char texturedQuadFragmentShader[]
Definition: Native.cpp:141
GLuint frameBufferTextureId
Definition: Native.cpp:94
A 3D floating point vector.
Definition: VectorTypes.h:83
GLuint createProgram(const char *vertexSource, const char *fragmentSource)
Definition: Native.cpp:104
GLuint texturedQuadLayerIndexLocation
Definition: Native.cpp:127
#define LOGE(...)
Definition: Native.cpp:36
GLfloat GLfloat f
Definition: gl2ext.h:2707
static Matrix matrixCameraLookAt(Vec3f eye, Vec3f center, Vec3f up)
Create and return a camera matrix.
Definition: Matrix.cpp:441
GLuint loadShader(GLenum shaderType, const char *shaderSource)
Definition: Native.cpp:69
GLfloat multiviewNormals[]
Definition: Native.cpp:204
GLuint multiviewModelLocation
Definition: Native.cpp:107
void renderFrame(void)
Definition: Native.cpp:1536
static Matrix createRotationY(float angle)
Create and return a rotation matrix around the y-axis matrix.
Definition: Matrix.cpp:511
GLuint frameBufferDepthTextureId
Definition: Native.cpp:95
#define GL_TEXTURE_2D_ARRAY
Definition: gl2ext.h:1612
bool setupFBO(int width, int height)
Definition: Native.cpp:468
static const char multiviewFragmentShader[]
Definition: Native.cpp:101
GLuint multiviewVertexNormalLocation
Definition: Native.cpp:100
GLuint multiviewProgram
Definition: Native.cpp:98
Matrix viewProjectionMatrix[VIEWS]
Definition: Native.cpp:139
GLuint fboWidth
Definition: Native.cpp:75
GLuint texturedQuadHighResTexCoordLocation
Definition: Native.cpp:125
float texturedQuadCoordinates[]
Definition: Native.cpp:223
GLushort multiviewIndices[]
Definition: Native.cpp:244
typedef void(GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC)(void)
GLint GLsizei width
Definition: gl2ext.h:179
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_multiview_NativeLibrary_step(JNIEnv *env, jobject obj)
Definition: Native.cpp:656
#define LOGI(...)
Definition: Native.cpp:35
GLuint frameBufferObjectId
Definition: Native.cpp:86
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLuint fboHeight
Definition: Native.cpp:76
GLuint program
Definition: gl2ext.h:1475
Matrix viewMatrix[VIEWS]
Definition: Native.cpp:138
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
static Matrix createRotationX(float angle)
Create and return a rotation matrix around the x-axis matrix.
Definition: Matrix.cpp:499
GLuint texturedQuadSamplerLocation
Definition: Native.cpp:126
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR glFramebufferTextureMultiviewOVR
Definition: Native.cpp:159
float texturedQuadHighResTexCoordinates[]
Definition: Native.cpp:247
GLuint screenHeight
Definition: Native.cpp:78
GLuint multiviewModelViewProjectionLocation
Definition: Native.cpp:105