46 #include <android/log.h>
48 #include <GLES3/gl3.h>
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__)
67 GLenum glError = glGetError(); \
68 if(glError != GL_NO_ERROR) { \
69 LOGE("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
74 using namespace MaliSDK;
156 #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
176 "precision mediump float;\n"
177 "precision mediump int;\n"
178 "precision mediump sampler2DArray;\n"
180 "in vec2 vLowResTexCoord;\n"
181 "in vec2 vHighResTexCoord;\n"
183 "out vec4 fragColor;\n"
186 "uniform sampler2D tex;\n"
188 "uniform sampler2DArray tex;\n"
191 "uniform int layerIndex;\n"
192 "uniform vec2 width_height;\n"
197 " vec2 distVec = (vec2(0.5) - vHighResTexCoord) / vec2(1, width_height.x/width_height.y);\n"
198 " float squaredDist = dot(distVec, distVec);\n"
200 " if( squaredDist > 0.25) { \n"
201 " fragColor = textureLod(tex, vec3(vLowResTexCoord, layerIndex), 0.0);\n"
204 " fragColor = textureLod(tex, vec3(vHighResTexCoord, layerIndex + 2), 0.0);\n"
208 " if( squaredDist > 0.23 && squaredDist < 0.27) { \n"
209 " fragColor += vec4(0.2,0.0,0.0,1.0);\n"
214 " vec4 lowResSample = texture(tex, vLowResTexCoord);\n"
216 " vec4 lowResSample = texture(tex, vec3(vLowResTexCoord, layerIndex));\n"
218 " fragColor = lowResSample;\n"
265 float increment = (2 *
M_PI) / (circleStep);
277 memcpy( VX_OutsetCircle, plane,
sizeof( plane ) );
281 for (
int j = 0; j < circleStep; ++j )
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.0
f;
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;
315 loopStep += increment;
320 GL_CHECK( glBufferData( GL_ARRAY_BUFFER, circleStep * 3 *
sizeof(
GLfloat ), VX_InsetCircle, GL_STATIC_DRAW ) );
322 GL_CHECK( glBufferData( GL_ARRAY_BUFFER, (circleStep + 4) * 3 *
sizeof(
GLfloat ), VX_OutsetCircle, GL_STATIC_DRAW ) );
326 for (
int i = 0; i < 4; ++i )
328 for (
int j = 0; j < circleStep / 4; j++ )
332 int temp = (i*(circleStep / 4)) + j + 4 + 1;
349 delete[] VX_InsetCircle;
350 delete[] VX_OutsetCircle;
359 GL_CHECK( glCompileShader( shader ) );
361 GL_CHECK( glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ) );
362 if ( compiled != GL_TRUE )
365 GL_CHECK( glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &infoLen ) );
369 char * logBuffer = (
char*) malloc( infoLen );
371 if ( logBuffer != NULL )
373 GL_CHECK( glGetShaderInfoLog( shader, infoLen, NULL, logBuffer ) );
374 LOGE(
"Could not Compile Shader %d:\n%s\n", shaderType, logBuffer );
379 GL_CHECK( glDeleteShader( shader ) );
399 GLuint createProgram(
const char* vertexSource,
const char * fragmentSource,
const int* vertexLength = NULL,
const int* fragmentLength = NULL )
401 GLuint vertexShader =
loadShader( GL_VERTEX_SHADER, vertexSource, vertexLength );
402 if ( vertexShader == 0 )
407 GLuint fragmentShader =
loadShader( GL_FRAGMENT_SHADER, fragmentSource, fragmentLength );
408 if ( fragmentShader == 0 )
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 )
425 GL_CHECK( glGetProgramiv( program, GL_INFO_LOG_LENGTH, &bufLength ) );
428 char* logBuffer = (
char*) malloc( bufLength );
430 if ( logBuffer != NULL )
432 GL_CHECK( glGetProgramInfoLog( program, bufLength, NULL, logBuffer ) );
433 LOGE(
"Could not link program:\n%s\n", logBuffer );
438 GL_CHECK( glDeleteProgram( program ) );
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 ) );
471 for ( uint8_t i = 0; i < 2; ++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 ) );
492 GLenum result =
GL_CHECK( glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER ) );
493 if ( result != GL_FRAMEBUFFER_COMPLETE )
495 LOGE(
"Framebuffer incomplete at %s:%i %i\n", __FILE__, __LINE__, (
int) result );
497 GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) );
522 GLenum result =
GL_CHECK( glCheckFramebufferStatus( GL_DRAW_FRAMEBUFFER ) );
523 if ( result != GL_FRAMEBUFFER_COMPLETE )
525 LOGE(
"Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__ );
527 GL_CHECK( glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ) );
539 LOGI(
"Running with masked foveated rendering." );
541 LOGI(
"Running with foveated rendering." );
543 #elif defined(MULTIVIEW)
544 LOGI(
"Running with multiview." );
546 LOGI(
"Running with regular stereo." );
549 int vertexShaderLength;
550 int fragmentShaderLength;
556 LOGI(
"Cannot get proc address for glFramebufferTexture2DMultisampleEXT.\n" );
557 exit( EXIT_FAILURE );
564 LOGI(
"Cannot get proc address for glRenderbufferStorageMultisampleEXT.\n" );
565 exit( EXIT_FAILURE );
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 )
573 LOGI(
"OpenGL ES 3.0 implementation does not support GL_OVR_multiview extension.\n" );
574 exit( EXIT_FAILURE );
582 LOGI(
"Cannot get proc address for glFramebufferTextureMultiviewOVR.\n" );
583 exit( EXIT_FAILURE );
590 LOGI(
"Cannot get proc address for glFramebufferTextureMultisampleMultiviewOVR.\n" );
591 exit( EXIT_FAILURE );
595 GL_CHECK( glDisable( GL_CULL_FACE ) );
596 GL_CHECK( glEnable( GL_DEPTH_TEST ) );
597 GL_CHECK( glDepthFunc( GL_LEQUAL ) );
611 LOGE(
"Could not create multiview FBO" );
619 LOGE(
"Could not create textured quad program" );
634 std::string roomVertexShader =
assetFolder +
"roomFoveated.vs";
635 #elif defined(MULTIVIEW)
636 std::string roomVertexShader =
assetFolder +
"roomMultiview.vs";
638 std::string roomVertexShader =
assetFolder +
"roomRegular.vs";
644 LOGE(
"Could not create multiview program" );
668 #if defined FOVEATED && defined MASK
690 const float FOV = M_PI_2;
691 double insetFOV = std::atan( std::tan( FOV / 2 ) * RATIO ) * 2;
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 };
714 LOGE(
"Cannot find room geom asset.\n" );
715 exit( EXIT_FAILURE );
717 LOGI(
"Asset Loaded" );
725 LOGI(
"Texture Loaded" );
732 GL_CHECK( glViewport( 0, 0, width, height ) );
735 GL_CHECK( glBindFramebuffer( GL_FRAMEBUFFER, frameBufferID ) );
737 GL_CHECK( glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) );
739 #if defined FOVEATED && defined MASK
740 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
754 GL_CHECK( glBindBuffer( GL_ARRAY_BUFFER, 0 ) );
755 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
759 GL_CHECK( glActiveTexture( GL_TEXTURE1 ) );
761 GL_CHECK( glActiveTexture( GL_TEXTURE2 ) );
763 GL_CHECK( glActiveTexture( GL_TEXTURE3 ) );
765 GL_CHECK( glActiveTexture( GL_TEXTURE4 ) );
770 for (
int i = 0; i <
VIEWS; ++i )
815 GLenum invalidateList[] = { GL_DEPTH_ATTACHMENT };
816 GL_CHECK( glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, invalidateList ) );
819 GL_CHECK( glBindFramebuffer( GL_FRAMEBUFFER, 0 ) );
829 for (
int i = 0; i < 2; ++i )
844 GL_CHECK( glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) );
851 for (
int i = 0; i < 2; i++ )
856 GL_CHECK( glActiveTexture( GL_TEXTURE0 ) );
889 GL_CHECK( glDrawArrays( GL_TRIANGLES, 0, 6 ) );
904 JNIEnv * env, jobject obj, jint
width, jint
height, jstring localPath );
906 JNIEnv * env, jobject obj );
910 JNIEnv * env, jobject obj, jint
width, jint
height, jstring localPath )
912 assetFolder =
"/data/data/com.arm.malideveloper.openglessdk.foveatedrendering/files/";
918 JNIEnv * env, jobject obj )
float texturedQuadLowResTexCoordinates[]
GLuint textureIdMetallicRoughness
GLuint maskVertexLocation
GLuint texturedQuadLowResTexCoordLocation
GLuint multiviewViewLocation
void renderToFBO(const int width, const int height, const GLuint frameBufferID)
float projectionMatrix[16]
GLuint multiviewVertexLocation
std::vector< GLushort > I_OutsetCircle
Matrix modelViewProjectionMatrix[VIEWS]
GLuint multiviewVertexTangentLocation
GLuint texturedQuadVertexLocation
float modelViewMatrix[16]
GLint GLsizei GLsizei height
GLuint textureQuadWidthHeight
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_foveatedrendering_NativeLibrary_step(JNIEnv *env, jobject obj)
GLuint texturedQuadProgram
GLuint multiviewTextureBump
Functions for manipulating matrices.
GLuint multiviewProjectionLocation
unsigned int get_indices_count() const
void(* PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei)
static Matrix createTranslation(float x, float y, float z)
Create and return a translation matrix.
GLuint multiviewTextureDiffuse
static Matrix createScaling(float x, float y, float z)
Create and return a scaling matrix.
const uint16_t TextureSize
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
float * getAsArray(void)
Get the matrix elements as a column major order array.
GLuint frameBufferTextureId
float * get_texture_coordinates0() const
GLuint masklInsetVertexArray
GLuint multiviewTextureNormal
A 3D floating point vector.
bool load_file(const std::string &a_path, char **a_buffer, int &a_bytes_read, const bool binary)
GLuint createProgram(const char *vertexSource, const char *fragmentSource)
GLuint texturedQuadLayerIndexLocation
GLuint multiviewVertexUVLocation
static Matrix matrixCameraLookAt(Vec3f eye, Vec3f center, Vec3f up)
Create and return a camera matrix.
GLuint loadShader(GLenum shaderType, const char *shaderSource)
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT glRenderbufferStorageMultisampleEXT
void(* PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)
GLuint multiviewModelLocation
GLuint multiviewTimeLocation
#define M_PI
The value of pi.
static const char texturedQuadFragmentShader[]
GLuint maskOutsetVertexArray
const uint8_t circleStepConst
float * get_tangents() const
void generateDepthCircleVBO(const uint8_t circleStep, const float radius)
static Matrix createRotationZ(float angle)
Create and return a rotation matrix around the z-axis matrix.
GLuint frameBufferDepthTextureId
#define GL_TEXTURE_2D_ARRAY
char * loadShaderFromFile(const std::string &filename, int *shaderLength)
bool setupFBO(int width, int height)
void(* PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLsizei, GLint, GLsizei)
GLuint multiviewVertexNormalLocation
bool createTexture(std::string filename, GLuint *textureLocation)
GLenum GLuint GLenum GLsizei length
Matrix viewProjectionMatrix[VIEWS]
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT glFramebufferTexture2DMultisampleEXT
GLuint texturedQuadHighResTexCoordLocation
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVR glFramebufferTextureMultisampleMultiviewOVR
float texturedQuadCoordinates[]
float * get_normals() const
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)
float * get_positions() const
struct GeometryProperties plane
GLuint frameBufferObjectId
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
GLuint textureQuadFoveatedRatio
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
void(* PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei)
unsigned int * get_indices() const
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
static Matrix createRotationX(float angle)
Create and return a rotation matrix around the x-axis matrix.
GLuint multiviewTextureMetallicRoughness
GLuint texturedQuadSamplerLocation
bool load(const std::string &a_path)
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR glFramebufferTextureMultiviewOVR
GLuint multiviewModelViewLocation
float texturedQuadHighResTexCoordinates[]
GLuint multiviewModelViewProjectionLocation