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) 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 #define FOVEATED
22 #define RATIO 0.3
23 #define MASK
24 #define RED
25 
26 #ifdef FOVEATED
27  #ifndef RATIO
28  #define RATIO 0.3
29  #endif
30 
31  #define VIEWS 4
32 #else
33  #undef RATIO
34  #define RATIO 1.0
35 
36  #ifdef MULTIVIEW
37  #define VIEWS 2
38  #else
39  #define VIEWS 1
40  #endif
41 #endif
42 
43 #include "Utils.h"
44 
45 #include <jni.h>
46 #include <android/log.h>
47 
48 #include <GLES3/gl3.h>
49 #include <EGL/egl.h>
50 
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <math.h>
54 #include <fstream>
55 
56 #include "model3d.h"
57 
58 #include "Matrix.h"
59 
60 #define LOG_TAG "Foveated_Sample"
61 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
62 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
63 
64 #define GL_CHECK(x) \
65  x; \
66  { \
67  GLenum glError = glGetError(); \
68  if(glError != GL_NO_ERROR) { \
69  LOGE("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
70  exit(1); \
71  } \
72  }
73 
74 using namespace MaliSDK;
79 
80 // Switch to define the structure holding the main view framebuffers
81 // Regular contains two FB, for left and right eye while the others
82 // use a single one based on multiview
83 #ifdef REGULAR
85 #else
87 #endif
88 
89 // Array of texture 2D containing left and right eye
90 #ifdef REGULAR
93 #else
96 #endif
97 
109 
112 
115 
118 
121 
130 
136 
143 float angle = 0;
144 
145 const uint8_t circleStepConst = 16;
146 
147 // The textures should be multiple of 2
148 const uint16_t TextureSize = 2048;
149 
150 std::string assetFolder;
152 
153 std::vector<GLushort> I_OutsetCircle;
154 
155 
156 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
157 
158 typedef void( *PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR )(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);
160 
161 // Define with multisampling multiview
162 typedef void( *PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR )(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei);
164 
165 // Texture 2D Multisample
168 
169 typedef void( *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT )(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
171 
172 /* Textured quad fragmentShader */
173 static const char texturedQuadFragmentShader[] =
174 "#version 300 es\n"
175 
176 "precision mediump float;\n"
177 "precision mediump int;\n"
178 "precision mediump sampler2DArray;\n"
179 
180 "in vec2 vLowResTexCoord;\n"
181 "in vec2 vHighResTexCoord;\n"
182 
183 "out vec4 fragColor;\n"
184 
185 #ifdef REGULAR
186 "uniform sampler2D tex;\n"
187 #else
188 "uniform sampler2DArray tex;\n"
189 #endif
190 
191 "uniform int layerIndex;\n"
192 "uniform vec2 width_height;\n"
193 
194 "void main()\n"
195 "{\n"
196 #ifdef FOVEATED
197 " vec2 distVec = (vec2(0.5) - vHighResTexCoord) / vec2(1, width_height.x/width_height.y);\n"
198 " float squaredDist = dot(distVec, distVec);\n"
199 
200 " if( squaredDist > 0.25) { \n"
201 " fragColor = textureLod(tex, vec3(vLowResTexCoord, layerIndex), 0.0);\n"
202 " } \n"
203 " else { \n"
204 " fragColor = textureLod(tex, vec3(vHighResTexCoord, layerIndex + 2), 0.0);\n"
205 " } \n"
206 
207 #ifdef RED
208 " if( squaredDist > 0.23 && squaredDist < 0.27) { \n"
209 " fragColor += vec4(0.2,0.0,0.0,1.0);\n"
210 " } \n"
211 #endif
212 #else
213 #ifdef REGULAR
214 " vec4 lowResSample = texture(tex, vLowResTexCoord);\n"
215 #else
216 " vec4 lowResSample = texture(tex, vec3(vLowResTexCoord, layerIndex));\n"
217 #endif
218 " fragColor = lowResSample;\n"
219 #endif
220 "}\n";
221 
222 /* Textured quad geometry */
224 {
225  -1.0f, -1.0f, -1.0f,
226  1.0f, -1.0f, -1.0f,
227  1.0f, 1.0f, -1.0f,
228 
229  -1.0f, -1.0f, -1.0f,
230  1.0f, 1.0f, -1.0f,
231  -1.0f, 1.0f, -1.0f
232 };
233 
234 /* Textured quad low resolution texture coordinates */
236 {
237  0, 0,
238  1, 0,
239  1, 1,
240 
241  0, 0,
242  1, 1,
243  0, 1
244 };
245 
246 /* Textured quad high resolution texture coordinates */
248 {
249  0, 0,
250  1, 0,
251  1, 1,
252 
253  0, 0,
254  1, 1,
255  0, 1
256 };
257 
258 void generateDepthCircleVBO( const uint8_t circleStep, const float radius )
259 {
260  // Generate the VAO for inset and outset masks
261  glGenVertexArrays( 1, &masklInsetVertexArray );
262  glGenVertexArrays( 1, &maskOutsetVertexArray );
263 
264  // Create the increment for the shape
265  float increment = (2 * M_PI) / (circleStep); // Increment for the circle
266 
267  GLfloat *VX_InsetCircle = new GLfloat[circleStep * 3]; // Inset mask
268  GLfloat *VX_OutsetCircle = new GLfloat[(circleStep + 4) * 3]; // Outset mask
269 
270  static const GLfloat plane[] = { // Plane around outset
271  1.0f, 1.0f, 0.0f,
272  -1.0f, 1.0f, 0.0f,
273  -1.0f, -1.0f, 0.0f,
274  1.0f, -1.0f, 0.0f
275  };
276 
277  memcpy( VX_OutsetCircle, plane, sizeof( plane ) ); // Copy the plane to the outset array
278 
279  // Create the coordinates data
280  double loopStep = 0;
281  for ( int j = 0; j < circleStep; ++j )
282  {
283  // Draw the inset mask
284  // The inset mask is dependent on the radius of the fovea region
285  // A small ratio (0.9) is applied in order to prevent uncovered area between the two masks
286  /*
287  X
288  XXX
289  XXXXXXX
290  XXXXXXXXX
291  XXXXXXX
292  XXX
293  X
294  */
295  VX_InsetCircle[(j * 3) + 0] = cos( loopStep ) * radius*0.9;
296  VX_InsetCircle[(j * 3) + 1] = sin( loopStep ) * radius*0.9;
297  VX_InsetCircle[(j * 3) + 2] = 0.0f;
298 
299  // Draw the outset mask
300  // The outset mask does not depend on the radius of fovea as it is only here to cover the corners
301  // A small ratio (1.1) is applied in order to prevent uncovered area between the two masks
302  /*
303  XXXXX XXXXX
304  XXX XXX
305  XX XX
306  X X
307  XX XX
308  XXX XXX
309  XXXXX XXXXX
310  */
311  VX_OutsetCircle[((4 + j) * 3) + 0] = cos( loopStep ) * (1.1);
312  VX_OutsetCircle[((4 + j) * 3) + 1] = sin( loopStep ) * (1.1);
313  VX_OutsetCircle[((4 + j) * 3) + 2] = 0.0f;
314 
315  loopStep += increment;
316  }
317 
318  // Upload data to the VAO
319  GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, masklInsetVertexArray ) );
320  GL_CHECK( glBufferData( GL_ARRAY_BUFFER, circleStep * 3 * sizeof( GLfloat ), VX_InsetCircle, GL_STATIC_DRAW ) );
321  GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, maskOutsetVertexArray ) );
322  GL_CHECK( glBufferData( GL_ARRAY_BUFFER, (circleStep + 4) * 3 * sizeof( GLfloat ), VX_OutsetCircle, GL_STATIC_DRAW ) );
323 
324 
325  // Create the index list for the outset mask
326  for ( int i = 0; i < 4; ++i )
327  {
328  for ( int j = 0; j < circleStep / 4; j++ )
329  {
330  I_OutsetCircle.push_back( i );
331  I_OutsetCircle.push_back( (i*(circleStep / 4)) + j + 4 );
332  int temp = (i*(circleStep / 4)) + j + 4 + 1;
333 
334  I_OutsetCircle.push_back( (temp == 4 + circleStep ? 4 : temp) );
335  }
336  I_OutsetCircle.push_back( i );
337  if ( i + 1 == 4 )
338  {
339  I_OutsetCircle.push_back( 4 );
340  I_OutsetCircle.push_back( 0 );
341  }
342  else
343  {
344  I_OutsetCircle.push_back( 4 + ((i + 1)*(circleStep / 4)) );
345  I_OutsetCircle.push_back( i + 1 );
346  }
347  }
348 
349  delete[] VX_InsetCircle;
350  delete[] VX_OutsetCircle;
351 }
352 
353 GLuint loadShader( GLenum shaderType, const char* shaderSource, const int* length = NULL )
354 {
355  GLuint shader = GL_CHECK( glCreateShader( shaderType ) );
356  if ( shader != 0 )
357  {
358  GL_CHECK( glShaderSource( shader, 1, &shaderSource, length ) );
359  GL_CHECK( glCompileShader( shader ) );
360  GLint compiled = 0;
361  GL_CHECK( glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ) );
362  if ( compiled != GL_TRUE )
363  {
364  GLint infoLen = 0;
365  GL_CHECK( glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &infoLen ) );
366 
367  if ( infoLen > 0 )
368  {
369  char * logBuffer = (char*) malloc( infoLen );
370 
371  if ( logBuffer != NULL )
372  {
373  GL_CHECK( glGetShaderInfoLog( shader, infoLen, NULL, logBuffer ) );
374  LOGE( "Could not Compile Shader %d:\n%s\n", shaderType, logBuffer );
375  free( logBuffer );
376  logBuffer = NULL;
377  }
378 
379  GL_CHECK( glDeleteShader( shader ) );
380  shader = 0;
381  }
382  }
383  }
384 
385  return shader;
386 }
387 
388 char* loadShaderFromFile( const std::string &filename, int* shaderLength )
389 {
390  // Load the shader file from the sdcard
391  char* shaderCode;
392 
393  Model3D::load_file( filename, &shaderCode, *shaderLength, false );
394 
395  // Load the shader
396  return shaderCode;
397 }
398 
399 GLuint createProgram( const char* vertexSource, const char * fragmentSource, const int* vertexLength = NULL, const int* fragmentLength = NULL )
400 {
401  GLuint vertexShader = loadShader( GL_VERTEX_SHADER, vertexSource, vertexLength );
402  if ( vertexShader == 0 )
403  {
404  return 0;
405  }
406 
407  GLuint fragmentShader = loadShader( GL_FRAGMENT_SHADER, fragmentSource, fragmentLength );
408  if ( fragmentShader == 0 )
409  {
410  return 0;
411  }
412 
413  GLuint program = GL_CHECK( glCreateProgram() );
414 
415  if ( program != 0 )
416  {
417  GL_CHECK( glAttachShader( program, vertexShader ) );
418  GL_CHECK( glAttachShader( program, fragmentShader ) );
419  GL_CHECK( glLinkProgram( program ) );
420  GLint linkStatus = GL_FALSE;
421  GL_CHECK( glGetProgramiv( program, GL_LINK_STATUS, &linkStatus ) );
422  if ( linkStatus != GL_TRUE )
423  {
424  GLint bufLength = 0;
425  GL_CHECK( glGetProgramiv( program, GL_INFO_LOG_LENGTH, &bufLength ) );
426  if ( bufLength > 0 )
427  {
428  char* logBuffer = (char*) malloc( bufLength );
429 
430  if ( logBuffer != NULL )
431  {
432  GL_CHECK( glGetProgramInfoLog( program, bufLength, NULL, logBuffer ) );
433  LOGE( "Could not link program:\n%s\n", logBuffer );
434  free( logBuffer );
435  logBuffer = NULL;
436  }
437  }
438  GL_CHECK( glDeleteProgram( program ) );
439  program = 0;
440  }
441  }
442  return program;
443 }
444 
445 bool createTexture( std::string filename, GLuint *textureLocation )
446 {
447  // Load the image in a buffer
448  char* pixelData;
449  int byteRead;
450 
451  Model3D::load_file( filename, &pixelData, byteRead, false );
452 
453  // Create and put the texture in memory
454  GL_CHECK( glGenTextures( 1, textureLocation ) );
455  GL_CHECK( glBindTexture( GL_TEXTURE_2D, *textureLocation ) );
456  GL_CHECK( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) );
457  GL_CHECK( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) );
458 
459  // Texture used here are power of two sized, check the data alignment if you want to replace them
460  GL_CHECK( glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, TextureSize, TextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char*) pixelData ) );
461 
462  // Destroy the image;
463  delete[] pixelData;
464 
465  return true;
466 }
467 
468 bool setupFBO( int width, int height )
469 {
470  #ifdef REGULAR
471  for ( uint8_t i = 0; i < 2; ++i )
472  {
473  // Generate colour texture
474  GL_CHECK( glGenTextures( 1, &frameBufferTextureId[i] ) );
475  GL_CHECK( glBindTexture( GL_TEXTURE_2D, frameBufferTextureId[i] ) );
476  GL_CHECK( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) );
477  GL_CHECK( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) );
478  GL_CHECK( glTexStorage2D( GL_TEXTURE_2D, 1, GL_RGBA8, width, height ) );
479 
480  // Generate depth texture
481 
482  GL_CHECK( glGenRenderbuffers( 1, &frameBufferDepthTextureId[i] ) );
483  GL_CHECK( glBindRenderbuffer( GL_RENDERBUFFER, frameBufferDepthTextureId[i] ) );
484  GL_CHECK( glRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, width, height ) );
485 
486  GL_CHECK( glGenFramebuffers( 1, &frameBufferObjectId[i] ) );
487  GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, frameBufferObjectId[i] ) );
488 
489  GL_CHECK( glFramebufferTexture2DMultisampleEXT( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTextureId[i], 0, 4 ) );
490  GL_CHECK( glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBufferDepthTextureId[i] ) );
491 
492  GLenum result = GL_CHECK( glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER ) );
493  if ( result != GL_FRAMEBUFFER_COMPLETE )
494  {
495  LOGE( "Framebuffer incomplete at %s:%i %i\n", __FILE__, __LINE__, (int) result );
496  /* Unbind framebuffer. */
497  GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) );
498  return false;
499  }
500  }
501  #else
502 
503  // Generate colour texture
504  GL_CHECK( glGenTextures( 1, &frameBufferTextureId ) );
506  GL_CHECK( glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) );
507  GL_CHECK( glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) );
508  GL_CHECK( glTexStorage3D( GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, VIEWS ) );
509 
510  // Generate depth texture
511  GL_CHECK( glGenTextures( 1, &frameBufferDepthTextureId ) );
513  GL_CHECK( glTexStorage3D( GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT24, width, height, VIEWS ) );
514 
515 
516  GL_CHECK( glGenFramebuffers( 1, &frameBufferObjectId ) );
517  GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, frameBufferObjectId ) );
518 
519  GL_CHECK( glFramebufferTextureMultisampleMultiviewOVR( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, frameBufferTextureId, 0, 4, 0, VIEWS ) );
520  GL_CHECK( glFramebufferTextureMultisampleMultiviewOVR( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBufferDepthTextureId, 0, 4, 0, VIEWS ) );
521 
522  GLenum result = GL_CHECK( glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER ) );
523  if ( result != GL_FRAMEBUFFER_COMPLETE )
524  {
525  LOGE( "Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__ );
526  /* Unbind framebuffer. */
527  GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) );
528  return false;
529  }
530  #endif
531 
532  return true;
533 }
534 
535 bool setupGraphics( int width, int height )
536 {
537  #ifdef FOVEATED
538  #ifdef MASK
539  LOGI( "Running with masked foveated rendering." );
540  #else
541  LOGI( "Running with foveated rendering." );
542  #endif
543  #elif defined(MULTIVIEW)
544  LOGI( "Running with multiview." );
545  #else
546  LOGI( "Running with regular stereo." );
547  #endif
548 
549  int vertexShaderLength;
550  int fragmentShaderLength;
551 
553  (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT) eglGetProcAddress( "glFramebufferTexture2DMultisampleEXT" );
555  {
556  LOGI( "Cannot get proc address for glFramebufferTexture2DMultisampleEXT.\n" );
557  exit( EXIT_FAILURE );
558  }
559 
561  (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT) eglGetProcAddress( "glRenderbufferStorageMultisampleEXT" );
563  {
564  LOGI( "Cannot get proc address for glRenderbufferStorageMultisampleEXT.\n" );
565  exit( EXIT_FAILURE );
566  }
567 
568  // Make sure the prerequisites are met
569  const GLubyte* extensions = GL_CHECK( glGetString( GL_EXTENSIONS ) );
570  const char * found_extension = strstr( (const char*) extensions, "GL_OVR_multiview" );
571  if ( NULL == found_extension )
572  {
573  LOGI( "OpenGL ES 3.0 implementation does not support GL_OVR_multiview extension.\n" );
574  exit( EXIT_FAILURE );
575  }
576  else
577  {
579  (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR) eglGetProcAddress( "glFramebufferTextureMultiviewOVR" );
581  {
582  LOGI( "Cannot get proc address for glFramebufferTextureMultiviewOVR.\n" );
583  exit( EXIT_FAILURE );
584  }
585 
587  (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR) eglGetProcAddress( "glFramebufferTextureMultisampleMultiviewOVR" );
589  {
590  LOGI( "Cannot get proc address for glFramebufferTextureMultisampleMultiviewOVR.\n" );
591  exit( EXIT_FAILURE );
592  }
593  }
594 
595  GL_CHECK( glDisable( GL_CULL_FACE ) );
596  GL_CHECK( glEnable( GL_DEPTH_TEST ) );
597  GL_CHECK( glDepthFunc( GL_LEQUAL ) );
598 
599  /* Setting screen width and height for use when rendering. */
600  screenWidth = width;
602 
603  // Set fbo size based on screen width/height
604  fboWidth = (screenWidth / 2) * RATIO;
606 
607  LOGI( "Resolution is %u-%u on %u-%u screen resolution", fboWidth, fboHeight, screenWidth, screenHeight );
608 
609  if ( !setupFBO( fboWidth, fboHeight ) )
610  {
611  LOGE( "Could not create multiview FBO" );
612  return false;
613  }
614 
615  /* Creating program for drawing textured quad. */
616  texturedQuadProgram = createProgram( loadShaderFromFile( assetFolder + "multiviewPlane.vs", &vertexShaderLength ), texturedQuadFragmentShader, &vertexShaderLength );
617  if ( texturedQuadProgram == 0 )
618  {
619  LOGE( "Could not create textured quad program" );
620  return false;
621  }
622 
623  /* Get attribute and uniform locations for textured quad program. */
624  texturedQuadVertexLocation = GL_CHECK( glGetAttribLocation( texturedQuadProgram, "attributePosition" ) );
625  texturedQuadLowResTexCoordLocation = GL_CHECK( glGetAttribLocation( texturedQuadProgram, "attributeLowResTexCoord" ) );
626  texturedQuadHighResTexCoordLocation = GL_CHECK( glGetAttribLocation( texturedQuadProgram, "attributeHighResTexCoord" ) );
627  texturedQuadSamplerLocation = GL_CHECK( glGetUniformLocation( texturedQuadProgram, "tex" ) );
628  texturedQuadLayerIndexLocation = GL_CHECK( glGetUniformLocation( texturedQuadProgram, "layerIndex" ) );
629  textureQuadFoveatedRatio = GL_CHECK( glGetUniformLocation( texturedQuadProgram, "foveatedRatio" ) );
630  textureQuadWidthHeight = GL_CHECK( glGetUniformLocation( texturedQuadProgram, "width_height" ) );
631 
632  /* Creating program for drawing object with multiview. */
633  #ifdef FOVEATED
634  std::string roomVertexShader = assetFolder + "roomFoveated.vs";
635  #elif defined(MULTIVIEW)
636  std::string roomVertexShader = assetFolder + "roomMultiview.vs";
637  #else
638  std::string roomVertexShader = assetFolder + "roomRegular.vs";
639  #endif // FOVEATED
640 
641  multiviewProgram = createProgram( loadShaderFromFile( roomVertexShader, &vertexShaderLength ), loadShaderFromFile( assetFolder + "roomPBR.fs", &fragmentShaderLength ), &vertexShaderLength, &fragmentShaderLength );
642  if ( multiviewProgram == 0 )
643  {
644  LOGE( "Could not create multiview program" );
645  return false;
646  }
647 
648  /* Get attribute and uniform locations for room program. */
649  multiviewVertexLocation = GL_CHECK( glGetAttribLocation( multiviewProgram, "vertexPosition" ) );
650  multiviewVertexNormalLocation = GL_CHECK( glGetAttribLocation( multiviewProgram, "vertexNormal" ) );
651  multiviewVertexTangentLocation = GL_CHECK( glGetAttribLocation( multiviewProgram, "vertexTangent" ) );
652  multiviewVertexUVLocation = GL_CHECK( glGetAttribLocation( multiviewProgram, "uvCoordinates" ) );
653 
654  multiviewTextureDiffuse = GL_CHECK( glGetUniformLocation( multiviewProgram, "TexDiffuse" ) );
655  multiviewTextureNormal = GL_CHECK( glGetUniformLocation( multiviewProgram, "TexNormal" ) );
656  multiviewTextureMetallicRoughness = GL_CHECK( glGetUniformLocation( multiviewProgram, "TexMetallicRoughness" ) );
657  multiviewTextureBump = GL_CHECK( glGetUniformLocation( multiviewProgram, "TexBump" ) );
658 
659  multiviewViewLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "View" ) );
660  multiviewProjectionLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "Projection" ) );
661  multiviewModelLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "Model" ) );
662  multiviewModelViewLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "ModelView" ) );
663  multiviewModelViewProjectionLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "ModelViewProjection" ) );
664  multiviewTimeLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "Time" ) );
665 
666  //multiviewTimeLocation = GL_CHECK( glGetUniformLocation( multiviewProgram, "time" ) );
667 
668  #if defined FOVEATED && defined MASK
669  maskProgram = createProgram( loadShaderFromFile( assetFolder + "mask.vs", &vertexShaderLength ), loadShaderFromFile( assetFolder + "mask.fs", &fragmentShaderLength ), &vertexShaderLength, &fragmentShaderLength );
670  if ( maskProgram == 0 )
671  {
672  LOGE( "Could not create mask program %i", maskProgram );
673  return false;
674  }
675  maskVertexLocation = GL_CHECK( glGetAttribLocation( maskProgram, "vertexPosition" ) );
676  maskTypeLocation = GL_CHECK( glGetUniformLocation( maskProgram, "maskType" ) );
677 
679  #endif
680 
681  /*
682  * Set up the perspective matrices for each view. Rendering is done twice in each eye position with different
683  * field of view. The narrower field of view should give half the size for the near plane in order to
684  * render the center of the scene at a higher resolution. The resulting high resolution and low resolution
685  * images will later be interpolated to create an image with higher resolution in the center of the screen
686  * than on the outer parts of the screen.
687  * 1.5707963268 rad = 90 degrees.
688  * 0.9272952188 rad = 53.1301024 degrees. This angle gives half the size for the near plane.
689  */
690  const float FOV = M_PI_2;
691  double insetFOV = std::atan( std::tan( FOV / 2 ) * RATIO ) * 2;
692 
693  projectionMatrix[0] = Matrix::matrixPerspective( FOV, (float) (width/2) / (float) height, 0.1f, 1000.0f );
694  projectionMatrix[1] = Matrix::matrixPerspective( FOV, (float) (width / 2) / (float) height, 0.1f, 1000.0f );
695  #ifdef FOVEATED
696  projectionMatrix[2] = Matrix::matrixPerspective( insetFOV, (float) (width / 2) / (float) height, 0.1f, 1000.0f );
697  projectionMatrix[3] = Matrix::matrixPerspective( insetFOV, (float) (width / 2) / (float) height, 0.1f, 1000.0f );
698  #endif
699 
700  /* Setting up model view matrices for each of the */
701  Vec3f leftCameraPos = { -0.5f, 0.0f, 5.0f };
702  Vec3f rightCameraPos = { 0.5f, 0.0f, 5.0f };
703  Vec3f lookAt = { 0.0f, 0.0f, 0.0f };
704  Vec3f upVec = { 0.0f, 1.0f, 0.0f };
705  viewMatrix[0] = Matrix::matrixCameraLookAt( leftCameraPos, lookAt, upVec );
706  viewMatrix[1] = Matrix::matrixCameraLookAt( rightCameraPos, lookAt, upVec );
707  #ifdef FOVEATED
708  viewMatrix[2] = Matrix::matrixCameraLookAt( leftCameraPos, lookAt, upVec );
709  viewMatrix[3] = Matrix::matrixCameraLookAt( rightCameraPos, lookAt, upVec );
710  #endif
711 
712  if ( !room.load( assetFolder + "room.geom" ) )
713  {
714  LOGE( "Cannot find room geom asset.\n" );
715  exit( EXIT_FAILURE );
716  }
717  LOGI( "Asset Loaded" );
718 
719  // Create and load textures
720  createTexture( assetFolder + "T_Exterior_D.raw", &textureIdDiffuse );
721  createTexture( assetFolder + "T_Exterior_N.raw", &textureIdNormal );
722  createTexture( assetFolder + "T_Exterior_M.raw", &textureIdMetallicRoughness );
723  createTexture( assetFolder + "T_Exterior_B.raw", &textureIdBump );
724 
725  LOGI( "Texture Loaded" );
726  return true;
727 }
728 
729 void renderToFBO( const int width, const int height, const GLuint frameBufferID )
730 {
731  /* Rendering to FBO. */
732  GL_CHECK( glViewport( 0, 0, width, height ) );
733 
734  /* Bind our framebuffer for rendering. */
735  GL_CHECK( glBindFramebuffer( GL_FRAMEBUFFER, frameBufferID ) );
736 
737  GL_CHECK( glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) );
738 
739  #if defined FOVEATED && defined MASK
740  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
741  // Render the mask
742  GL_CHECK( glUseProgram( maskProgram ) );
743  GL_CHECK( glEnableVertexAttribArray( maskVertexLocation ) );
744  GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, masklInsetVertexArray ) );
745  GL_CHECK( glVertexAttribPointer( maskVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0 ) );
746  GL_CHECK( glUniform1ui( maskTypeLocation, 1 ) );
747  GL_CHECK( glDrawArrays( GL_TRIANGLE_FAN, 0, circleStepConst ) );
748  GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, maskOutsetVertexArray ) );
749  GL_CHECK( glVertexAttribPointer( maskVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0 ) );
750  GL_CHECK( glUniform1ui( maskTypeLocation, 2 ) );
751  GL_CHECK( glDrawElements( GL_TRIANGLES, I_OutsetCircle.size(), GL_UNSIGNED_SHORT, &I_OutsetCircle[0] ) );
752  GL_CHECK( glDisableVertexAttribArray( maskVertexLocation ) );
753 
754  GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, 0 ) );
755  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
756  #endif
757 
758  // Upload diffuse texture
759  GL_CHECK( glActiveTexture( GL_TEXTURE1 ) );
760  GL_CHECK( glBindTexture( GL_TEXTURE_2D, textureIdDiffuse ) );
761  GL_CHECK( glActiveTexture( GL_TEXTURE2 ) );
762  GL_CHECK( glBindTexture( GL_TEXTURE_2D, textureIdNormal ) );
763  GL_CHECK( glActiveTexture( GL_TEXTURE3 ) );
764  GL_CHECK( glBindTexture( GL_TEXTURE_2D, textureIdMetallicRoughness ) );
765  GL_CHECK( glActiveTexture( GL_TEXTURE4 ) );
766  GL_CHECK( glBindTexture( GL_TEXTURE_2D, textureIdBump ) );
767 
768  modelMatrix = Matrix::createTranslation( 0.0, 30.0, -45.0 ) * Matrix::createScaling( 0.2, 0.2, 0.2 ) * Matrix::createRotationX( -90.0 ) * Matrix::createRotationZ( 90.0 );
769 
770  for ( int i = 0; i < VIEWS; ++i )
771  {
774  }
775 
776  GL_CHECK( glUseProgram( multiviewProgram ) );
777 
778  GL_CHECK( glUniformMatrix4fv( multiviewViewLocation, VIEWS, GL_FALSE, viewMatrix[0].getAsArray() ) );
779  GL_CHECK( glUniformMatrix4fv( multiviewProjectionLocation, VIEWS, GL_FALSE, projectionMatrix[0].getAsArray() ) );
780  GL_CHECK( glUniformMatrix4fv( multiviewModelViewLocation, VIEWS, GL_FALSE, modelViewMatrix[0].getAsArray() ) );
781  GL_CHECK( glUniformMatrix4fv( multiviewModelViewProjectionLocation, VIEWS, GL_FALSE, modelViewProjectionMatrix[0].getAsArray() ) );
782 
783  // Upload vertex location
784  GL_CHECK( glVertexAttribPointer( multiviewVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, room.get_positions() ) );
785  GL_CHECK( glEnableVertexAttribArray( multiviewVertexLocation ) );
786 
787  // Upload vertex normal
788  GL_CHECK( glVertexAttribPointer( multiviewVertexNormalLocation, 3, GL_FLOAT, GL_FALSE, 0, room.get_normals() ) );
789  GL_CHECK( glEnableVertexAttribArray( multiviewVertexNormalLocation ) );
790 
791  // Upload vertex UV
792  GL_CHECK( glVertexAttribPointer( multiviewVertexUVLocation, 3, GL_FLOAT, GL_FALSE, 0, room.get_texture_coordinates0() ) );
793  GL_CHECK( glEnableVertexAttribArray( multiviewVertexUVLocation ) );
794 
795  // Upload vertex tangent
796  GL_CHECK( glVertexAttribPointer( multiviewVertexTangentLocation, 3, GL_FLOAT, GL_FALSE, 0, room.get_tangents() ) );
797  GL_CHECK( glEnableVertexAttribArray( multiviewVertexTangentLocation ) );
798 
799  /* Upload model view projection matrices. */
800  GL_CHECK( glUniformMatrix4fv( multiviewModelLocation, 1, GL_FALSE, modelMatrix.getAsArray() ) );
801 
802  GL_CHECK( glUniform1i( multiviewTextureDiffuse, 1 ) );
803  GL_CHECK( glUniform1i( multiviewTextureNormal, 2 ) );
804  GL_CHECK( glUniform1i( multiviewTextureMetallicRoughness, 3 ) );
805  GL_CHECK( glUniform1i( multiviewTextureBump, 4 ) );
806 
807  // Upload time
809 
810 
811  /* Draw the room. */
812  GL_CHECK( glDrawElements( GL_TRIANGLES, room.get_indices_count() * 3, GL_UNSIGNED_INT, room.get_indices() ) );
813 
814  // Invalidate the depth buffer
815  GLenum invalidateList[] = { GL_DEPTH_ATTACHMENT };
816  GL_CHECK( glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, invalidateList ) );
817 
818  /* Go back to the backbuffer for rendering to the screen. */
819  GL_CHECK( glBindFramebuffer( GL_FRAMEBUFFER, 0 ) );
820 }
821 
823 {
824  // Start the render frame timer
826 
827 
828  #ifdef REGULAR
829  for ( int i = 0; i < 2; ++i )
830  {
832 
833  }
834  #else
835  /*
836  * Render the scene to the multiview texture. This will render to 4 different layers of the texture,
837  * using different projection and view matrices for each layer.
838  */
840  #endif
841 
842 
843  GL_CHECK( glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ) );
844  GL_CHECK( glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) );
845 
846  /*
847  * Render the multiview texture layers to separate viewports. Each viewport corresponds to one eye,
848  * and will use two different texture layers from the multiview texture, one with a wide field of view
849  * and one with a narrow field of view.
850  */
851  for ( int i = 0; i < 2; i++ )
852  {
853  glViewport( i * screenWidth / 2, 0, screenWidth / 2, screenHeight );
854 
855  /* Use the texture array that was drawn to using multiview. */
856  GL_CHECK( glActiveTexture( GL_TEXTURE0 ) );
857  #ifdef REGULAR
858  GL_CHECK( glBindTexture( GL_TEXTURE_2D, frameBufferTextureId[i] ) );
859  #else
861  #endif
862 
863  GL_CHECK( glUseProgram( texturedQuadProgram ) );
864 
865  /* Upload vertex attributes. */
866  GL_CHECK( glVertexAttribPointer( texturedQuadVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, texturedQuadCoordinates ) );
867  GL_CHECK( glEnableVertexAttribArray( texturedQuadVertexLocation ) );
868  GL_CHECK( glVertexAttribPointer( texturedQuadLowResTexCoordLocation, 2, GL_FLOAT,
869  GL_FALSE, 0, texturedQuadLowResTexCoordinates ) );
870  GL_CHECK( glEnableVertexAttribArray( texturedQuadLowResTexCoordLocation ) );
871 
872  #ifdef FOVEATED
873  GL_CHECK( glVertexAttribPointer( texturedQuadHighResTexCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texturedQuadHighResTexCoordinates ) );
874  GL_CHECK( glEnableVertexAttribArray( texturedQuadHighResTexCoordLocation ) );
875  #endif
876 
877  /*
878  * Upload uniforms. The layerIndex is used to choose what layer of the array texture to sample from.
879  * The shader will use the given layerIndex and layerIndex + 2, where layerIndex gives the layer with
880  * the wide field of view, where the entire scene has been rendered, and layerIndex + 2 gives the layer
881  * with the narrow field of view, where only the center of the scene has been rendered.
882  */
883  GL_CHECK( glUniform1i( texturedQuadSamplerLocation, 0 ) );
884  GL_CHECK( glUniform1i( texturedQuadLayerIndexLocation, i ) );
885  GL_CHECK( glUniform1f( textureQuadFoveatedRatio, RATIO ) );
886  GL_CHECK( glUniform2f( textureQuadWidthHeight, screenWidth / 2.0, screenHeight ) );
887 
888  /* Draw textured quad using the multiview texture. */
889  GL_CHECK( glDrawArrays( GL_TRIANGLES, 0, 6 ) );
890 
891  Stats::EndFrame();
892 
893  if ( Stats::nbFrame >= 60 )
894  {
895  LOGI( "Current FPS: %f", Stats::GetFPS() );
896  Stats::Clear();
897  }
898  }
899 }
900 
901 extern "C"
902 {
904  JNIEnv * env, jobject obj, jint width, jint height, jstring localPath );
906  JNIEnv * env, jobject obj );
907 };
908 
910  JNIEnv * env, jobject obj, jint width, jint height, jstring localPath )
911 {
912  assetFolder = "/data/data/com.arm.malideveloper.openglessdk.foveatedrendering/files/";
913 
914  setupGraphics( width, height );
915 }
916 
918  JNIEnv * env, jobject obj )
919 {
920  renderFrame();
921 }
void setupGraphics(int width, int height)
Definition: Native.cpp:1256
float texturedQuadLowResTexCoordinates[]
Definition: Native.cpp:235
GLuint textureIdMetallicRoughness
Definition: Native.cpp:116
GLuint maskVertexLocation
Definition: Native.cpp:132
uint32_t nbFrame
Definition: Utils.h:28
GLint textureLocation
Definition: Native.cpp:140
#define GL_CHECK(x)
Definition: Native.cpp:64
#define VIEWS
Definition: Native.cpp:31
GLuint texturedQuadLowResTexCoordLocation
Definition: Native.cpp:124
GLuint screenWidth
Definition: Native.cpp:77
GLuint multiviewViewLocation
Definition: Native.cpp:103
#define LOGE(...)
Definition: Native.cpp:62
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
std::vector< GLushort > I_OutsetCircle
Definition: Native.cpp:153
Matrix modelViewProjectionMatrix[VIEWS]
Definition: Native.cpp:141
GLuint multiviewVertexTangentLocation
Definition: Native.cpp:101
void StartFrame()
Definition: Utils.h:32
GLuint texturedQuadVertexLocation
Definition: Native.cpp:123
float modelViewMatrix[16]
Definition: Native.cpp:157
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLuint textureQuadWidthHeight
Definition: Native.cpp:129
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_foveatedrendering_NativeLibrary_step(JNIEnv *env, jobject obj)
Definition: Native.cpp:917
GLuint texturedQuadProgram
Definition: Native.cpp:122
Matrix modelMatrix
Definition: Native.cpp:142
GLuint multiviewTextureBump
Definition: Native.cpp:120
Functions for manipulating matrices.
Definition: Matrix.h:31
GLuint multiviewProjectionLocation
Definition: Native.cpp:106
unsigned int get_indices_count() const
Definition: model3d.cpp:372
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
#define RATIO
Definition: Native.cpp:22
GLuint multiviewTextureDiffuse
Definition: Native.cpp:111
static Matrix createScaling(float x, float y, float z)
Create and return a scaling matrix.
Definition: Matrix.cpp:403
const uint16_t TextureSize
Definition: Native.cpp:148
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
Definition: Matrix.cpp:425
GLuint textureIdBump
Definition: Native.cpp:119
float angle
Definition: Native.cpp:158
float * getAsArray(void)
Get the matrix elements as a column major order array.
Definition: Matrix.cpp:78
GLuint frameBufferTextureId
Definition: Native.cpp:94
float * get_texture_coordinates0() const
Definition: model3d.cpp:392
GLuint masklInsetVertexArray
Definition: Native.cpp:134
GLuint multiviewTextureNormal
Definition: Native.cpp:114
A 3D floating point vector.
Definition: VectorTypes.h:83
bool load_file(const std::string &a_path, char **a_buffer, int &a_bytes_read, const bool binary)
Definition: model3d.cpp:33
GLuint createProgram(const char *vertexSource, const char *fragmentSource)
Definition: Native.cpp:104
GLuint texturedQuadLayerIndexLocation
Definition: Native.cpp:127
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint multiviewVertexUVLocation
Definition: Native.cpp:102
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
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT glRenderbufferStorageMultisampleEXT
Definition: Native.cpp:170
void(* PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)
Definition: Native.cpp:169
GLuint multiviewModelLocation
Definition: Native.cpp:107
GLuint multiviewTimeLocation
Definition: Native.cpp:108
#define M_PI
The value of pi.
Definition: Mathematics.h:37
static const char texturedQuadFragmentShader[]
Definition: Native.cpp:173
GLuint maskOutsetVertexArray
Definition: Native.cpp:135
void renderFrame(void)
Definition: Native.cpp:1536
GLuint maskProgram
Definition: Native.cpp:131
const uint8_t circleStepConst
Definition: Native.cpp:145
float * get_tangents() const
Definition: model3d.cpp:397
void generateDepthCircleVBO(const uint8_t circleStep, const float radius)
Definition: Native.cpp:258
static Matrix createRotationZ(float angle)
Create and return a rotation matrix around the z-axis matrix.
Definition: Matrix.cpp:523
GLuint frameBufferDepthTextureId
Definition: Native.cpp:95
#define GL_TEXTURE_2D_ARRAY
Definition: gl2ext.h:1612
char * loadShaderFromFile(const std::string &filename, int *shaderLength)
Definition: Native.cpp:388
bool setupFBO(int width, int height)
Definition: Native.cpp:468
void(* PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei)
Definition: Native.cpp:162
void Clear()
Definition: Utils.h:59
float GetFPS()
Definition: Utils.h:49
GLuint multiviewVertexNormalLocation
Definition: Native.cpp:100
GLuint multiviewProgram
Definition: Native.cpp:98
bool createTexture(std::string filename, GLuint *textureLocation)
Definition: Native.cpp:445
GLenum GLuint GLenum GLsizei length
Definition: gl2ext.h:134
Matrix viewProjectionMatrix[VIEWS]
Definition: Native.cpp:139
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT glFramebufferTexture2DMultisampleEXT
Definition: Native.cpp:167
GLuint fboWidth
Definition: Native.cpp:75
void EndFrame()
Definition: Utils.h:37
GLuint texturedQuadHighResTexCoordLocation
Definition: Native.cpp:125
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR glFramebufferTextureMultisampleMultiviewOVR
Definition: Native.cpp:163
float texturedQuadCoordinates[]
Definition: Native.cpp:223
GLuint maskTypeLocation
Definition: Native.cpp:133
float * get_normals() const
Definition: model3d.cpp:387
typedef void(GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC)(void)
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_foveatedrendering_NativeLibrary_init(JNIEnv *env, jobject obj, jint width, jint height, jstring localPath)
Definition: Native.cpp:909
float * get_positions() const
Definition: model3d.cpp:382
Model3D::Model3D room
Definition: Native.cpp:151
GLint GLsizei width
Definition: gl2ext.h:179
struct GeometryProperties plane
GLuint frameBufferObjectId
Definition: Native.cpp:86
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
GLuint textureQuadFoveatedRatio
Definition: Native.cpp:128
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
void(* PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei)
Definition: Native.cpp:166
unsigned int * get_indices() const
Definition: model3d.cpp:402
#define LOGI(...)
Definition: Native.cpp:61
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 multiviewTextureMetallicRoughness
Definition: Native.cpp:117
std::string assetFolder
Definition: Native.cpp:150
GLuint texturedQuadSamplerLocation
Definition: Native.cpp:126
bool load(const std::string &a_path)
Definition: model3d.cpp:183
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR glFramebufferTextureMultiviewOVR
Definition: Native.cpp:159
uint32_t totalNbFrame
Definition: Utils.h:29
GLuint textureIdDiffuse
Definition: Native.cpp:110
GLuint textureIdNormal
Definition: Native.cpp:113
GLuint multiviewModelViewLocation
Definition: Native.cpp:104
float texturedQuadHighResTexCoordinates[]
Definition: Native.cpp:247
GLuint screenHeight
Definition: Native.cpp:78
GLuint multiviewModelViewProjectionLocation
Definition: Native.cpp:105