### Build and Install Android App Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/README.md Use Gradle to build and install the debug version of the application. Then, use ADB to start the main activity. ```bash $ gradlew installDebug $ adb shell am start -n com.oculus.sample/.SphericalPlayerActivity ``` -------------------------------- ### Install and Launch Application Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Commands to install the debug APK onto an Android device and then launch the SphericalPlayerActivity. ```bash gradlew installDebug adb shell am start -n com.oculus.sample/.SphericalPlayerActivity ``` -------------------------------- ### Instantiate SphericalVideoPlayer Programmatically Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Example of how to create and set up a SphericalVideoPlayer instance directly in your Activity code. ```java SphericalVideoPlayer player = new SphericalVideoPlayer(this); setContentView(player); ``` -------------------------------- ### play() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Starts video playback. Only starts if the MediaPlayer is not already playing. ```APIDOC ## play() ### Description Starts video playback. Only starts if the MediaPlayer is not already playing. ### Note Called automatically by the prepared listener after `prepareAsync()` completes. ``` -------------------------------- ### playWhenReady() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Signals that playback should begin once the render surface is ready. Call this before the SurfaceTexture is created to ensure video preparation starts automatically when the display surface is available. ```APIDOC ## playWhenReady() ### Description Signals that playback should begin once the render surface is ready. Call this before the SurfaceTexture is created to ensure video preparation starts automatically when the display surface is available. ### Request Example ```java player.setVideoURIPath(videoPath); player.playWhenReady(); ``` ``` -------------------------------- ### EGLRenderTarget Constructor Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Creates a new EGLRenderTarget instance and initializes the EGL display and rendering context. This is typically called once during setup. ```java public EGLRenderTarget() ``` ```java EGLRenderTarget eglTarget = new EGLRenderTarget(); // EGL context is now ready ``` -------------------------------- ### Projection Matrix Setup Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Defines a perspective projection with a 70-degree field of view. ```glsl projectionMatrix = perspective( fovy=70°, aspect=width/height, near=1.0, far=1000.0 ) ``` -------------------------------- ### Multiple Index Buffer Sizes Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Example calculation for distributing indices across multiple buffers. This is useful when the total number of indices exceeds the limit for a single buffer. ```plaintext indices[0].size = 48,600 (194,400 / 4) indices[1].size = 48,600 indices[2].size = 48,600 indices[3].size = 48,600 ``` -------------------------------- ### Single Index Buffer Size Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Example calculation for the size of a single index buffer when all indices fit within one buffer. This is relevant for optimizing buffer management. ```plaintext indices[0].size = 194,400 ``` -------------------------------- ### Handle Failed External Texture Creation Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This example illustrates how to handle the failure of generating an OpenGL external texture. It checks if the returned texture ID is -1, indicating an error, and suggests falling back to an alternative rendering method. ```java int textureId = GLHelpers.generateExternalTexture(); if (textureId == -1) { Log.e(TAG, "Failed to generate external texture"); // Fall back to alternative rendering method } ``` -------------------------------- ### onCreate Method Implementation Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Initializes the activity, sets up the video player, and requests necessary permissions. Ensures the screen stays on during playback. ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); videoPlayer = (SphericalVideoPlayer) findViewById(R.id.spherical_video_player); videoPlayer.setVideoURIPath(videoPath); videoPlayer.playWhenReady(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); requestExternalStoragePermission(); } ``` -------------------------------- ### onCreate(Bundle) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Initializes the activity, inflates layout, initializes the video player, and requests runtime permissions. ```APIDOC ## onCreate(Bundle) ### Description Initializes the activity, inflates layout, initializes the video player, and requests runtime permissions. ### Method `protected void onCreate(Bundle savedInstanceState)` ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); videoPlayer = (SphericalVideoPlayer) findViewById(R.id.spherical_video_player); videoPlayer.setVideoURIPath(videoPath); videoPlayer.playWhenReady(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); requestExternalStoragePermission(); } ``` ### Response #### Success Response (void) N/A #### Response Example N/A ``` -------------------------------- ### EGL Error Format Example Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md This is an example of the error format produced by EGL when an operation fails. The `abortWithEGLError()` method uses `EGL14.eglGetError()` and `GLUtils.getEGLErrorString()` to generate such messages. ```java eglCreateContext: EGL error: 0x300c: EGL_BAD_ATTRIBUTE ``` -------------------------------- ### init() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Initializes the EGL display connection, chooses an EGL configuration with RGBA-8888 format, and creates an OpenGL ES 2.0 context. Configures 8-bit color and alpha channels. ```APIDOC ## init() ### Description Initializes the EGL display connection, chooses an EGL configuration with RGBA-8888 format, and creates an OpenGL ES 2.0 context. Configures 8-bit color and alpha channels. ### Method `public void init()` ### Parameters None ### Returns - `void` ### Throws - `RuntimeException` - with EGL error details if initialization fails ### Configuration Details - Red channel: 8 bits - Green channel: 8 bits - Blue channel: 8 bits - Alpha channel: 8 bits - Renderable type: EGL_OPENGL_ES2_BIT - OpenGL ES version: 2.0 ### Example ```java EGLRenderTarget target = new EGLRenderTarget(); // Display already initialized via constructor // Can call again to reinitialize if needed target.init(); ``` ``` -------------------------------- ### Declare SphericalVideoPlayer in XML Layout Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Example of how to include the SphericalVideoPlayer in an Android layout XML file, specifying its ID and dimensions. ```xml ``` -------------------------------- ### Application Level Configuration Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Sets up core application properties including backup, hardware acceleration, icon, label, RTL support, and the main theme. Enables GPU acceleration by default and uses the AppTheme for Material Design. ```xml ``` -------------------------------- ### Gradle Build Process Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Details the steps involved in the Gradle build process for compiling Java sources, resources, packaging the APK, and signing the application. ```bash gradle build ├─ Compile Java sources (src/main/java) ├─ Compile resources (AndroidManifest.xml, layouts, drawables) ├─ Package APK └─ Sign with debug/release key ``` -------------------------------- ### Get Total Sphere Indices Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Retrieves the total number of indices across all index buffers, calculated as the sum of values returned by `getNumIndices()`. ```java public int getTotalIndices() ``` -------------------------------- ### Initialization Sequence for 360 Video Player Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Details the steps from `onCreate` to `initRenderThread` and `onSurfaceAvailable` in the render thread. This sequence is crucial for setting up the video player and the rendering environment. ```plaintext 1. onCreate() [Main Thread] │ ├─ setContentView(R.layout.activity_main) ├─ Set video path ├─ playWhenReady() ├─ requestExternalStoragePermission() │ ├─ [Permission dialog → User allows] │ └─ init() └─ setSurfaceTextureListener() 2. onSurfaceTextureAvailable() [Main Thread, TextureView] │ └─ initRenderThread(surface, width, height) [Main Thread] │ ├─ Create RenderThread (HandlerThread) ├─ Start render thread ├─ Send MSG_SURFACE_AVAILABLE │ └─ [RenderThread] onSurfaceAvailable() [RenderThread] │ ├─ EGLRenderTarget.init() │ └─ Create EGL display, config, context │ ├─ EGLRenderTarget.createRenderSurface(surface) │ └─ Create EGL window surface │ ├─ Choreographer.postFrameCallback() │ └─ Register for vsync callbacks │ ├─ glViewport(), matrix setup ├─ SphericalSceneRenderer.init() │ ├─ Load shaders │ ├─ Create sphere mesh │ ├─ Cache attribute/uniform locations │ └─ Setup vertex attributes │ └─ prepareVideo(videoPath) └─ MediaPlayer.setDataSource() └─ MediaPlayer.prepareAsync() ``` -------------------------------- ### Get Sphere Vertex Stride Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Retrieves the stride in bytes between consecutive vertex records. This value is crucial for correctly setting up `glVertexAttribPointer()` calls. ```java public int getVerticesStride() ``` -------------------------------- ### Validate OpenGL State After Operations Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This example demonstrates how to validate OpenGL state after critical operations like glClear and glDrawElements to catch errors immediately. ```java GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLHelpers.checkGlError("glClear"); // Validates state after each operation GLES20.glDrawElements(GLES20.GL_TRIANGLES, count, GLES20.GL_UNSIGNED_SHORT, buffer); GLHelpers.checkGlError("glDrawElements"); // Catches draw errors immediately ``` -------------------------------- ### Prepare Model-View-Projection Matrix Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Combines the projection-view matrix with the model matrix to create the final MVP matrix. ```glsl mvpMatrix = pvMatrix * modelMatrix ``` -------------------------------- ### Get Sphere Indices Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Retrieves an array of ShortBuffer objects, each containing triangle indices for rendering. The number of buffers corresponds to the `numIndexBuffers` specified during construction. ```java public ShortBuffer[] getIndices() ``` -------------------------------- ### Create Shader Program Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Compiles vertex and fragment shaders, attaches them to a new program, and links the program. Returns the linked program handle or 0 on failure. ```java private static int createProgram(String vertexSource, String fragmentSource) ``` -------------------------------- ### Recover from Video Preparation Failure Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This code demonstrates how to recover from a video preparation failure by attempting to retry loading the video or switching to a different video source. ```java public void onPrepared(MediaPlayer mp) { try { play(); } catch (Exception e) { Log.e(TAG, "Failed to start playback: " + e.getMessage()); // Attempt to retry or switch to different video retryVideoLoad(); } } ``` -------------------------------- ### Get Sphere Index Counts Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Returns an array of integers representing the count of indices in each index buffer. The sum of these counts equals the total number of indices. ```java public int[] getNumIndices() ``` -------------------------------- ### Get Sphere Vertices Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Retrieves the direct FloatBuffer containing vertex position and texture coordinate data. Each vertex is composed of 5 floats (x, y, z, s, t). ```java public FloatBuffer getVertices() ``` -------------------------------- ### Play Video When Ready Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Signals that playback should begin once the render surface is ready. This should be called before the SurfaceTexture is created to ensure automatic preparation when the display surface is available. ```java player.setVideoURIPath(videoPath); player.playWhenReady(); ``` -------------------------------- ### Initialize and Render Sphere in SphericalSceneRenderer Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Demonstrates the initialization of a Sphere object and its rendering within the SphericalSceneRenderer. It shows how to set up vertex attributes and draw elements using OpenGL ES. ```java public class SphericalSceneRenderer { public SphericalSceneRenderer(Context context) { sphere = new Sphere(SPHERE_SLICES, 0.f, 0.f, 0.f, SPHERE_RADIUS, SPHERE_INDICES_PER_VERTEX); // Setup vertex attributes GLES20.glEnableVertexAttribArray(aPositionLocation); GLES20.glVertexAttribPointer(aPositionLocation, 3, GLES20.GL_FLOAT, false, sphere.getVerticesStride(), sphere.getVertices()); GLES20.glEnableVertexAttribArray(aTextureCoordLocation); GLES20.glVertexAttribPointer(aTextureCoordLocation, 2, GLES20.GL_FLOAT, false, sphere.getVerticesStride(), sphere.getVertices().duplicate().position(3)); } public void onDrawFrame(...) { for (int j = 0; j < sphere.getNumIndices().length; ++j) { GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphere.getNumIndices()[j], GLES20.GL_UNSIGNED_SHORT, sphere.getIndices()[j]); } } } ``` -------------------------------- ### Initialize and Configure MediaPlayer for Video Playback Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/types.md Sets up an Android MediaPlayer instance for decoding and playing video. Configures the audio stream, looping, and the video surface, then prepares for asynchronous playback. ```java videoPlayerInternal = new MediaPlayer(); videoPlayerInternal.setSurface(renderThread.getVideoDecodeSurface()); videoPlayerInternal.setAudioStreamType(AudioManager.STREAM_MUSIC); videoPlayerInternal.setDataSource(context, Uri.parse(videoPath), null); videoPlayerInternal.setLooping(true); videoPlayerInternal.prepareAsync(); // Async preparation // ... onPrepared callback fires videoPlayerInternal.start(); // ... playback continues until releaseResources() videoPlayerInternal.stop(); videoPlayerInternal.release(); ``` -------------------------------- ### Request External Storage Permission Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Checks for and requests READ_EXTERNAL_STORAGE permission if not already granted. If granted, it proceeds to initialize the player. ```java private void requestExternalStoragePermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); } else { init(); } } ``` -------------------------------- ### Get Uniform Variable Location Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Retrieve the location index for a named uniform variable. This method caches the result of glGetUniformLocation and throws an exception if the uniform is not found in the shader. ```java ShaderProgram program = new ShaderProgram(vertexSrc, fragmentSrc); int mvpLoc = program.getUniform("uMVPMatrix"); int texMatrixLoc = program.getUniform("uTextureMatrix"); GLES20.glUniformMatrix4fv(mvpLoc, 1, false, mvpMatrix, 0); GLES20.glUniformMatrix4fv(texMatrixLoc, 1, false, texMatrix, 0); ``` -------------------------------- ### SphericalVideoPlayer Constructor with Context, AttributeSet, and DefStyleAttr Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance with custom style attributes. This constructor allows for more advanced styling and theming. ```java public SphericalVideoPlayer(Context context, AttributeSet attrs, int defStyleAttr) ``` -------------------------------- ### Get Vertex Attribute Location Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Obtain the location index for a named vertex attribute. This method caches the result of glGetAttribLocation and throws an exception if the attribute is not found in the shader. ```java ShaderProgram program = new ShaderProgram(vertexSrc, fragmentSrc); int positionLoc = program.getAttribute("aPosition"); int texCoordLoc = program.getAttribute("aTextureCoord"); GLES20.glEnableVertexAttribArray(positionLoc); GLES20.glVertexAttribPointer(positionLoc, 3, GLES20.GL_FLOAT, false, stride, vertexBuffer); ``` -------------------------------- ### EGLRenderTarget Constructor Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Creates a new EGLRenderTarget and immediately initializes the EGL display and rendering context. Automatically calls init() during construction. ```APIDOC ## EGLRenderTarget() ### Description Creates a new EGLRenderTarget and immediately initializes the EGL display and rendering context. Automatically calls `init()` during construction. ### Method Constructor ### Parameters None ### Returns - `EGLRenderTarget` - New EGLRenderTarget instance ### Throws - `RuntimeException` - if EGL initialization fails ### Example ```java EGLRenderTarget eglTarget = new EGLRenderTarget(); // EGL context is now ready ``` ``` -------------------------------- ### Get Shader Program Handle Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Retrieve the OpenGL ES program object handle for the ShaderProgram. This handle is necessary to activate the shader program for rendering using GLES20.glUseProgram(). ```java ShaderProgram program = new ShaderProgram(vertexSrc, fragmentSrc); int handle = program.getShaderHandle(); GLES20.glUseProgram(handle); ``` -------------------------------- ### ShaderProgram API Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/README.md A wrapper class for GLSL shader compilation and linking. It provides methods to get attribute and uniform locations, retrieve shader handles, and release shader resources. ```APIDOC ## ShaderProgram Methods ### `getAttribute(String name)` Gets the location of a vertex attribute. ### `getUniform(String name)` Gets the location of a uniform variable. ### `getShaderHandle()` Returns the handle of the compiled shader program. ### `release()` Releases the shader program resources. ``` -------------------------------- ### SphericalVideoPlayer Constructor with Context Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance using a single context parameter. This is typically used when instantiating the player programmatically. ```java public SphericalVideoPlayer(Context context) ``` -------------------------------- ### Retrieve Shader Attribute and Uniform Locations Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md Get attribute and uniform locations from a ShaderProgram. This code will throw a RuntimeException if the specified attribute or uniform name is not found in the compiled shader program. ```java ShaderProgram program = new ShaderProgram(vertexSrc, fragmentSrc); int posLoc = program.getAttribute("aPosition"); // Throws if "aPosition" not in vertex shader int mvpLoc = program.getUniform("uMVPMatrix"); // Throws if "uMVPMatrix" not in program ``` -------------------------------- ### GLHelpers Static Methods Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Static utility methods for OpenGL operations. ```APIDOC ## GLHelpers ### Description Provides static utility methods for common OpenGL operations. ### Static Methods - `generateExternalTexture()`: Create external texture. - `checkGlError(String)`: Validate GL state. ``` -------------------------------- ### Check EGL Context Before Getting Video Decode Surface Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This code snippet shows how to safely obtain a video decode surface by first checking for a valid EGL context. If the context is not valid, it logs an error and defers surface creation. ```java if (eglRenderTarget.hasValidContext()) { Surface decodeSurface = getVideoDecodeSurface(); } else { Log.e(TAG, "EGL context not ready"); // Defer surface creation } ``` -------------------------------- ### Ensure Correct Call Order for Video Playback Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This snippet demonstrates the correct sequence of method calls to avoid an IllegalStateException related to render thread initialization. Ensure the video URI is set and playback is signaled before the render thread is available. ```java // Ensure correct call order: videoPlayer.setVideoURIPath(path); // Set path first videoPlayer.playWhenReady(); // Signal ready to play // Wait for onSurfaceTextureAvailable() to call initRenderThread() ``` -------------------------------- ### EGLRenderTarget Lifecycle Integration Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Demonstrates the typical sequence of operations for using EGLRenderTarget within a rendering thread. This includes initialization, surface creation, per-frame rendering, and cleanup. ```java 1. **Construction**: `EGLRenderTarget()` — initializes display and context 2. **Surface available**: `createRenderSurface(surfaceTexture)` — creates window surface 3. **Per frame**: `makeCurrent()`, draw operations, `swapBuffers()` 4. **Cleanup**: `release()` — destroys context and surface ``` -------------------------------- ### Prepare Projection-View Matrix Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Combines projection and view matrices to form the projection-view matrix. ```glsl pvMatrix = projectionMatrix * viewMatrix ``` -------------------------------- ### SphericalSceneRenderer Constructor Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Initializes the renderer, loading shaders, creating geometry, and preparing OpenGL state. Ensure to call release() when done to clean up resources. ```java public SphericalSceneRenderer(Context context) ``` ```java SphericalSceneRenderer renderer = new SphericalSceneRenderer(context); // Use renderer in onDrawFrame() each frame // ... // Cleanup renderer.release(); ``` -------------------------------- ### Initialize Video Player View and Render Thread Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Sets up the TextureView's SurfaceTextureListener to manage the render thread and surface availability. This snippet also makes the video player view visible. ```java private void init() { videoPlayer.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { videoPlayer.initRenderThread(surface, width, height); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { videoPlayer.releaseResources(); return false; } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } }); videoPlayer.setVisibility(View.VISIBLE); } ``` -------------------------------- ### SphericalVideoPlayer(Context) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance with a single context parameter. This constructor is used when creating the player programmatically. ```APIDOC ## SphericalVideoPlayer(Context) ### Description Creates a new SphericalVideoPlayer instance with a single context parameter. ### Method public SphericalVideoPlayer(Context context) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java SphericalVideoPlayer player = new SphericalVideoPlayer(this); setContentView(player); ``` ### Response #### Success Response (200) New SphericalVideoPlayer instance #### Response Example None ``` -------------------------------- ### Handle READ_EXTERNAL_STORAGE Permission Denial Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md This snippet illustrates the error handling for when a user denies READ_EXTERNAL_STORAGE permission. It shows a toast message and prevents video player initialization. ```java Toast: "Access not granted for reading video file :(" ``` -------------------------------- ### Configure Vertex Attributes with Sphere Data Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Demonstrates how to use `getVertices()` and `getVerticesStride()` to configure OpenGL ES vertex attribute pointers for position and texture coordinates. ```java FloatBuffer vertices = sphere.getVertices(); int vertexStride = sphere.getVerticesStride(); GLES20.glEnableVertexAttribArray(aPositionLocation); GLES20.glVertexAttribPointer(aPositionLocation, 3, GLES20.GL_FLOAT, false, vertexStride, vertices); // For texture coordinates, use offset into same buffer GLES20.glEnableVertexAttribArray(aTexCoordLocation); GLES20.glVertexAttribPointer(aTexCoordLocation, 2, GLES20.GL_FLOAT, false, vertexStride, vertices.duplicate().position(3)); ``` -------------------------------- ### Initialize ShaderProgram Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Initializes a ShaderProgram with vertex and fragment shaders. Caches attribute and uniform locations for efficiency and sets up the OpenGL program for use. ```java public class SphericalSceneRenderer { private ShaderProgram shaderProgram; public SphericalSceneRenderer(Context context) { String vertexSrc = readShaderFile(context, R.raw.video_vertex_shader); String fragmentSrc = readShaderFile(context, R.raw.video_fragment_shader); shaderProgram = new ShaderProgram(vertexSrc, fragmentSrc); // Cache attribute locations for efficiency aPositionLocation = shaderProgram.getAttribute("aPosition"); aTextureCoordLocation = shaderProgram.getAttribute("aTextureCoord"); uMVPMatrixLocation = shaderProgram.getUniform("uMVPMatrix"); uTextureMatrixLocation = shaderProgram.getUniform("uTextureMatrix"); GLES20.glUseProgram(shaderProgram.getShaderHandle()); GLES20.glEnableVertexAttribArray(aPositionLocation); GLES20.glEnableVertexAttribArray(aTextureCoordLocation); } public void release() { shaderProgram.release(); } } ``` -------------------------------- ### EGLRenderTarget Initialization Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Initializes the EGL display connection, chooses an EGL configuration, and creates an OpenGL ES 2.0 context. Can be called again to reinitialize. ```java public void init() ``` ```java EGLRenderTarget target = new EGLRenderTarget(); // Display already initialized via constructor // Can call again to reinitialize if needed target.init(); ``` -------------------------------- ### Activity Intent Filter Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Defines the main launcher entry point for the application, making this activity the first one to be displayed when the app is launched. ```xml ``` -------------------------------- ### Create ShaderProgram Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Instantiate a ShaderProgram by providing GLSL source code for vertex and fragment shaders. This constructor handles compilation and linking, throwing a RuntimeException on failure. ```java String vertexSource = readShaderFile("vertex.glsl"); String fragmentSource = readShaderFile("fragment.glsl"); ShaderProgram program = new ShaderProgram(vertexSource, fragmentSource); // Use the program GLES20.glUseProgram(program.getShaderHandle()); ``` -------------------------------- ### release() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/ShaderProgram.md Deletes the shader program and frees GPU resources. Sets the program handle to -1. Call during cleanup or when the program is no longer needed. ```APIDOC ## release() ### Description Deletes the shader program and frees GPU resources. Sets the program handle to -1. Call during cleanup or when the program is no longer needed. ### Returns - **void** ### Example ```java @Override protected void onDestroy() { program.release(); super.onDestroy(); } ``` ``` -------------------------------- ### Touch Input Flow for 360 Video Player Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Describes how touch events are processed, from `onTouchEvent` on the main thread to `onScroll` in the `SimpleOnGestureListener`, and finally queued to the render thread for camera updates. ```plaintext onTouchEvent() [Main Thread, TextureView] │ └─ GestureDetector.onTouchEvent() │ └─ SimpleOnGestureListener.onScroll(e1, e2, distanceX, distanceY) │ ├─ Create Message(MSG_ON_SCROLL) ├─ Wrap deltaX, deltaY in ScrollDeltaHolder │ └─ handler.sendMessage() [Queue to RenderThread] │ └─ onScroll(deltaHolder) [RenderThread] │ ├─ lon += deltaX * DRAG_FRICTION ├─ lat -= deltaY * DRAG_FRICTION │ └─ pendingCameraUpdate = true └─ Next vsync → updateCamera() recomputes view matrix ``` -------------------------------- ### Initialize ShortBuffer for Index Data Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/types.md Allocates a direct ByteBuffer on the native heap and converts it to a ShortBuffer for storing triangle index data. ```java ShortBuffer indices = ByteBuffer.allocateDirect(capacity) .order(ByteOrder.nativeOrder()) .asShortBuffer(); ``` -------------------------------- ### Spherical Player Activity Configuration Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Configures the main player activity, enabling hardware acceleration and enforcing landscape screen orientation for an optimal viewing experience. ```xml ``` -------------------------------- ### Project Architecture Diagram Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Visual representation of the application's layered architecture, showing the interaction between UI, Video Player, Rendering, and OpenGL Utilities. ```text ┌─────────────────────────────────────────┐ │ User Interface Layer │ │ SphericalPlayerActivity (Entry Point) │ └──────────────────┬──────────────────────┘ │ ┌──────────────────┴──────────────────────┐ │ Video Player Layer │ │ SphericalVideoPlayer (TextureView) │ │ + RenderThread (HandlerThread) │ └──────────────────┬──────────────────────┘ │ ┌──────────────────┴──────────────────────────────────────┐ │ Rendering Layer │ │ ┌──────────────────┐ ┌────────────────────┐ │ │ │ EGLRenderTarget │ │ SphericalScene │ │ │ │ (EGL context) │ │ Renderer │ │ │ │ │ │ (Shader + sphere) │ │ │ └──────────────────┘ └────────────────────┘ │ └──────────────────┬──────────────────────────────────────┘ │ ┌──────────────────┴──────────────────────────────────────┐ │ OpenGL Utilities Layer │ │ ┌─────────────┐ ┌──────────┐ ┌──────────┐ │ │ │ GLHelpers │ │ Shader │ │ Sphere │ │ │ │ (Errors) │ │ Program │ │ (Mesh) │ │ │ └─────────────┘ └──────────┘ └──────────┘ │ └──────────────────────────────────────────────────────────┘ ``` -------------------------------- ### SphericalPlayerActivity Static Methods Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Static utility methods available on SphericalPlayerActivity. ```APIDOC ## SphericalPlayerActivity ### Description Entry point activity for the player, with static utility methods. ### Static Methods - `toast()`: Display a toast message. - `readRawTextFile()`: Read text from a raw resource file. ``` -------------------------------- ### Batched Drawing with Multiple Index Buffers Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Demonstrates batched drawing using multiple index buffers for rendering spheres. This approach reduces per-draw-call complexity, especially for larger spheres. ```java for (int j = 0; j < sphere.getNumIndices().length; ++j) { GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphere.getNumIndices()[j], GLES20.GL_UNSIGNED_SHORT, sphere.getIndices()[j]); } ``` -------------------------------- ### Handle Shader Resource Loading Errors Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md Check for null return values when loading shader source files. If null, it indicates a failure to load the resource, requiring fallback shaders or aborting the process. ```java String vertexShader = SphericalPlayerActivity.readRawTextFile(context, R.raw.video_vertex_shader); if (vertexShader == null) { Log.e(TAG, "Failed to load vertex shader"); // Use fallback shader or abort } ``` -------------------------------- ### initRenderThread(SurfaceTexture surface, int width, int height) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Initializes the background render thread with the display surface and dimensions. Creates an OpenGL ES rendering context and begins the vsync callback loop. Called when the TextureView surface becomes available. ```APIDOC ## initRenderThread(SurfaceTexture surface, int width, int height) ### Description Initializes the background render thread with the display surface and dimensions. Creates an OpenGL ES rendering context and begins the vsync callback loop. Called when the TextureView surface becomes available. ### Parameters #### Path Parameters - **surface** (SurfaceTexture) - Required - SurfaceTexture from the TextureView - **width** (int) - Required - Surface width in pixels - **height** (int) - Required - Surface height in pixels ### Request Example ```java videoPlayer.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { videoPlayer.initRenderThread(surface, width, height); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { videoPlayer.releaseResources(); return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } }); ``` ``` -------------------------------- ### Handle EGL Initialization Errors Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/errors.md Catch RuntimeExceptions during EGL initialization to handle failures gracefully. This is useful when setting up rendering surfaces or contexts. ```java try { EGLRenderTarget eglTarget = new EGLRenderTarget(); eglTarget.createRenderSurface(surfaceTexture); } catch (RuntimeException e) { Log.e(TAG, "EGL initialization failed: " + e.getMessage()); // Fall back to software rendering or abort } ``` -------------------------------- ### Direct ByteBuffer Allocation for GPU Data Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Demonstrates the allocation of direct ByteBuffers for GPU-bound data, ensuring efficient memory management for vertex and index buffers. Direct buffers are not managed by the Java GC and must be handled explicitly if released. ```java ByteBuffer.allocateDirect(size) .order(ByteOrder.nativeOrder()) .asFloatBuffer() // or .asShortBuffer() ``` -------------------------------- ### Sphere Constructor Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Creates a sphere mesh with specified geometric parameters and organizes indices into multiple buffers for efficient rendering. ```APIDOC ## Sphere(int nSlices, float x, float y, float z, float r, int numIndexBuffers) ### Description Creates a sphere mesh with specified geometric parameters and organizes indices into multiple buffers for efficient rendering. ### Parameters #### Path Parameters - **nSlices** (int) - Required - Number of slices in horizontal direction (>1 and <=180); same count used for vertical direction - **x** (float) - Required - X coordinate of sphere origin - **y** (float) - Required - Y coordinate of sphere origin - **z** (float) - Required - Z coordinate of sphere origin - **r** (float) - Required - Radius of the sphere - **numIndexBuffers** (int) - Required - Number of index buffers to distribute indices across ### Returns New Sphere instance with generated mesh data ### Throws RuntimeException if nSlices is too large (results in vertex count > Short.MAX_VALUE) ### Example ```java // Create a sphere centered at origin with radius 500 Sphere sphere = new Sphere( 180, // nSlices: high tessellation for smooth surface 0.0f, // x: origin 0.0f, // y: origin 0.0f, // z: origin 500.0f, // radius: large for immersive rendering 1 // numIndexBuffers: single buffer for simplicity ); ``` ``` -------------------------------- ### makeCurrent() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Makes the EGL context current for the calling thread. All subsequent OpenGL ES calls execute on this context and render to the associated surface. Required before issuing any OpenGL commands. ```APIDOC ## makeCurrent() ### Description Makes the EGL context current for the calling thread. All subsequent OpenGL ES calls execute on this context and render to the associated surface. Required before issuing any OpenGL commands. ### Method `public void makeCurrent()` ### Parameters None ### Returns - `void` ### Throws - `RuntimeException` - if `eglMakeCurrent` fails ### Example ```java // On render thread eglTarget.makeCurrent(); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); eglTarget.swapBuffers(); ``` ``` -------------------------------- ### SphericalVideoPlayer(Context, AttributeSet, int) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance with custom style attributes. This constructor allows for more advanced customization through style attributes defined in themes or styles. ```APIDOC ## SphericalVideoPlayer(Context, AttributeSet, int) ### Description Creates a new SphericalVideoPlayer instance with custom style attributes. ### Method public SphericalVideoPlayer(Context context, AttributeSet attrs, int defStyleAttr) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) New SphericalVideoPlayer instance #### Response Example None ``` -------------------------------- ### Configure Vertex Attributes with Stride Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Shows how to use `getVerticesStride()` to specify the byte stride for `glVertexAttribPointer()`, ensuring correct data interpretation for position and texture coordinates. ```java int stride = sphere.getVerticesStride(); // Returns 20 GLES20.glVertexAttribPointer(positionLoc, 3, GLES20.GL_FLOAT, false, stride, vertices); GLES20.glVertexAttribPointer(texCoordLoc, 2, GLES20.GL_FLOAT, false, stride, vertices.duplicate().position(3)); ``` -------------------------------- ### createRenderSurface(SurfaceTexture) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Creates an EGL window surface from a SurfaceTexture. Automatically calls makeCurrent() to activate the context for subsequent OpenGL calls. Required before any OpenGL ES drawing operations. ```APIDOC ## createRenderSurface(SurfaceTexture) ### Description Creates an EGL window surface from a SurfaceTexture. Automatically calls `makeCurrent()` to activate the context for subsequent OpenGL calls. Required before any OpenGL ES drawing operations. ### Method `public void createRenderSurface(SurfaceTexture surfaceTexture)` ### Parameters #### Path Parameters - **surfaceTexture** (SurfaceTexture) - Yes - — - Android SurfaceTexture from TextureView to render to ### Returns - `void` ### Throws - `RuntimeException` - if surface creation fails or context is invalid ### Example ```java public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { eglTarget.createRenderSurface(surface); // OpenGL context is now current and ready GLES20.glViewport(0, 0, width, height); GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); } ``` ``` -------------------------------- ### release() Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Destroys the EGL surface and context, releasing all GPU resources. Cleans up EGL state by setting handles to EGL_NO_SURFACE, EGL_NO_CONTEXT, and EGL_NO_DISPLAY. Call during cleanup or when activity is destroyed. ```APIDOC ## release() ### Description Destroys the EGL surface and context, releasing all GPU resources. Cleans up EGL state by setting handles to EGL_NO_SURFACE, EGL_NO_CONTEXT, and EGL_NO_DISPLAY. Call during cleanup or when activity is destroyed. ### Method `public void release()` ### Parameters None ### Returns - `void` ### Throws - None ### Example ```java @Override protected void onDestroy() { eglTarget.release(); super.onDestroy(); } ``` ``` -------------------------------- ### Sphere Constructor Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/Sphere.md Creates a sphere mesh with specified geometric parameters and organizes indices into multiple buffers for efficient rendering. Ensure nSlices is between 2 and 180, and the resulting vertex count does not exceed Short.MAX_VALUE. ```java public Sphere(int nSlices, float x, float y, float z, float r, int numIndexBuffers) ``` ```java // Create a sphere centered at origin with radius 500 Sphere sphere = new Sphere( 180, // nSlices: high tessellation for smooth surface 0.0f, // x: origin 0.0f, // y: origin 0.0f, // z: origin 500.0f, // radius: large for immersive rendering 1 // numIndexBuffers: single buffer for simplicity ); ``` -------------------------------- ### View Matrix Calculation Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Calculates camera position using spherical coordinates (longitude, latitude) and sets up the view matrix. ```glsl phi = 90 - latitude theta = longitude x = 100 * sin(phi) * cos(theta) y = 100 * cos(phi) z = 100 * sin(phi) * sin(theta) viewMatrix = lookAt(x, y, z, 0, 0, 0, 0, 1, 0) ``` -------------------------------- ### Render Loop for 360 Video Player Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Illustrates the render loop triggered by VSync events. It covers updating the video texture, camera view, and drawing the frame using OpenGL ES. ```plaintext [VSync Event] │ ├─ Choreographer.postFrameCallback() │ └─ onFrame(frameTimeNanos) │ └─ RenderThread.handler.sendEmptyMessage(MSG_VSYNC) │ └─ onVSync() [RenderThread] │ ├─ eglTarget.makeCurrent() │ ├─ videoSurfaceTexture.updateTexImage() │ └─ Latch latest video frame │ ├─ videoSurfaceTexture.getTransformMatrix(matrix) │ ├─ updateCamera() │ └─ Convert lon/lat to view matrix │ ├─ renderer.onDrawFrame(...) │ ├─ glClear() │ ├─ glBindTexture(videoTexture) │ ├─ Set uniforms (MVP, texture matrix) │ └─ glDrawElements() [for each index buffer] │ └─ eglTarget.swapBuffers() └─ Present frame to TextureView ``` -------------------------------- ### onRequestPermissionsResult(int, String[], int[]) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Handles the response from Android's runtime permission request. Initializes the renderer if permission is granted, or shows a toast if denied. ```APIDOC ## onRequestPermissionsResult(int, String[], int[]) ### Description Handles the response from Android's runtime permission request. Initializes the renderer if permission is granted, or shows a toast if denied. ### Method `public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)` ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```java @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode != PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) { return; } if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { init(); } else { toast(this, "Access not granted for reading video file :("); } } ``` ### Response #### Success Response (void) N/A #### Response Example N/A ``` -------------------------------- ### ShaderProgram Methods Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Methods for interacting with compiled shader programs. ```APIDOC ## ShaderProgram ### Description Wrapper for shader compilation, providing access to shader attributes and uniforms. ### Methods - `getAttribute(String)`: Get attribute location. - `getUniform(String)`: Get uniform location. - `getShaderHandle()`: Get program handle. - `release()`: Cleanup. ``` -------------------------------- ### GLHelpers API Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/README.md Contains utility methods for OpenGL ES operations. This includes functions for generating external textures and checking for OpenGL errors. ```APIDOC ## GLHelpers Methods ### `generateExternalTexture()` Generates an external texture suitable for video playback. ### `checkGlError(String op)` Checks for OpenGL errors after an operation and logs them if any occur. ``` -------------------------------- ### readRawTextFile(Context, int) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalPlayerActivity.md Reads the entire contents of a raw resource file into a String. Used to load shader source code. ```APIDOC ## readRawTextFile(Context, int) ### Description Reads the entire contents of a raw resource file into a String. Used to load shader source code. ### Method public static String ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **context** (Context) - Required - Application context for resource access - **resId** (int) - Required - Raw resource ID (e.g., `R.raw.video_vertex_shader`) ### Response #### Success Response (String) String — Full file contents with newlines preserved; null on IOException ### Example ```java String vertexShaderSrc = SphericalPlayerActivity.readRawTextFile(context, R.raw.video_vertex_shader); String fragmentShaderSrc = SphericalPlayerActivity.readRawTextFile(context, R.raw.video_fragment_shader); ShaderProgram program = new ShaderProgram(vertexShaderSrc, fragmentShaderSrc); ``` ``` -------------------------------- ### SphericalVideoPlayer(Context, AttributeSet) Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance initialized from XML layout attributes. This constructor is typically used by the Android layout inflater when the player is declared in an XML file. ```APIDOC ## SphericalVideoPlayer(Context, AttributeSet) ### Description Creates a new SphericalVideoPlayer instance initialized from XML layout attributes. Used by the Android layout inflater. ### Method public SphericalVideoPlayer(Context context, AttributeSet attrs) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```xml ``` ### Response #### Success Response (200) New SphericalVideoPlayer instance #### Response Example None ``` -------------------------------- ### Create Render Surface from SurfaceTexture Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/EGLRenderTarget.md Creates an EGL window surface from a SurfaceTexture and makes the OpenGL context current. This is required before any OpenGL ES drawing operations. ```java public void createRenderSurface(SurfaceTexture surfaceTexture) ``` ```java public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { eglTarget.createRenderSurface(surface); // OpenGL context is now current and ready GLES20.glViewport(0, 0, width, height); GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); } ``` -------------------------------- ### App Build Configuration Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Defines essential build settings for the Android application, including SDK versions, build tools, and minimum/target SDKs. Specifies the application ID and configures the release build type. ```gradle release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } ``` -------------------------------- ### SphericalVideoPlayer Constructor with Context and AttributeSet Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalVideoPlayer.md Creates a new SphericalVideoPlayer instance initialized from XML layout attributes. This constructor is used by the Android layout inflater when the player is declared in an XML file. ```java public SphericalVideoPlayer(Context context, AttributeSet attrs) ``` -------------------------------- ### SphericalVideoPlayer Methods Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/PROJECT-OVERVIEW.md Methods for controlling video playback and source. ```APIDOC ## SphericalVideoPlayer ### Description Provides methods to control video playback and set the video source. ### Methods - `setVideoURIPath(String)`: Set video source. - `playWhenReady()`: Signal start on surface ready. - `initRenderThread(SurfaceTexture, int, int)`: Initialize renderer. - `play()`: Start playback. - `releaseResources()`: Cleanup. ``` -------------------------------- ### Activity Main Layout XML Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/configuration.md Defines the layout for the 360 video player activity. The SphericalVideoPlayer is initially hidden and set to fill the screen. ```xml ``` -------------------------------- ### Model Matrix Rotation Source: https://github.com/fbsamples/360-video-player-for-android/blob/master/_autodocs/api-reference/SphericalSceneRenderer.md Initializes the model matrix with a 90-degree upward rotation. ```glsl modelMatrix = rotateX(90°) ```