| /* Copyright 2016 Google Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef VR_GVR_CAPI_INCLUDE_GVR_H_ |
| #define VR_GVR_CAPI_INCLUDE_GVR_H_ |
| |
| #ifdef __ANDROID__ |
| #include <jni.h> |
| #endif |
| |
| #include <stdint.h> |
| #include <stdlib.h> |
| |
| #if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER) |
| #include <array> |
| #include <memory> |
| #include <vector> |
| #endif |
| |
| #include "vr/gvr/capi/include/gvr_types.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /// @defgroup base Google VR Base C API |
| /// @brief This is the Google VR C API. It supports clients writing VR |
| /// experiences for head mounted displays that consist of a mobile phone and a |
| /// VR viewer. |
| /// |
| /// Example API usage: |
| /// |
| /// #ifdef __ANDROID__ |
| /// // On Android, the gvr_context should almost always be obtained from |
| /// // the Java GvrLayout object via |
| /// // GvrLayout.getGvrApi().getNativeGvrContext(). |
| /// gvr_context* gvr = ...; |
| /// #else |
| /// gvr_context* gvr = gvr_create(); |
| /// #endif |
| /// |
| /// gvr_initialize_gl(gvr); |
| /// |
| /// gvr_buffer_viewport_list* viewport_list = |
| /// gvr_buffer_viewport_list_create(gvr); |
| /// gvr_get_recommended_buffer_viewports(gvr, viewport_list); |
| /// gvr_buffer_viewport* left_eye_vp = gvr_buffer_viewport_create(gvr); |
| /// gvr_buffer_viewport* right_eye_vp = gvr_buffer_viewport_create(gvr); |
| /// gvr_buffer_viewport_list_get_item(viewport_list, 0, left_eye_vp); |
| /// gvr_buffer_viewport_list_get_item(viewport_list, 1, right_eye_vp); |
| /// |
| /// while (client_app_should_render) { |
| /// // A client app should be ready for the render target size to change |
| /// // whenever a new QR code is scanned, or a new viewer is paired. |
| /// gvr_sizei render_target_size = |
| /// gvr_get_maximum_effective_render_target_size(gvr); |
| /// // The maximum effective render target size can be very large, most |
| /// // applications need to scale down to compensate. |
| /// render_target_size.width /= 2; |
| /// render_target_size.height /= 2; |
| /// gvr_swap_chain_resize_buffer(swap_chain, 0, render_target_size); |
| /// |
| /// // This function will depend on your render loop's implementation. |
| /// gvr_clock_time_point next_vsync = AppGetNextVsyncTime(); |
| /// |
| /// const gvr_mat4f head_view = |
| /// gvr_get_head_space_from_start_space_transform(gvr, next_vsync); |
| /// const gvr_mat4f left_eye_view = MatrixMultiply( |
| /// gvr_get_eye_from_head_matrix(gvr, GVR_LEFT_EYE), head_view); |
| /// const gvr::Mat4f right_eye_view = MatrixMultiply( |
| /// gvr_get_eye_from_head_matrix(gvr, GVR_RIGHT_EYE), head_view); |
| /// |
| /// // Insert client rendering code here. |
| /// |
| /// AppSetRenderTarget(offscreen_texture_id); |
| /// |
| /// AppDoSomeRenderingForEye( |
| /// gvr_buffer_viewport_get_source_uv(left_eye_view), |
| /// left_eye_matrix); |
| /// AppDoSomeRenderingForEye( |
| /// gvr_buffer_viewport_get_source_uv(right_eye_view), |
| /// right_eye_matrix); |
| /// AppSetRenderTarget(primary_display); |
| /// |
| /// gvr_frame_submit(&frame, viewport_list, head_view); |
| /// } |
| /// |
| /// // Cleanup memory. |
| /// gvr_buffer_viewport_list_destroy(&viewport_list); |
| /// gvr_buffer_viewport_destroy(&left_eye_vp); |
| /// gvr_buffer_viewport_destroy(&right_eye_vp); |
| /// |
| /// #ifdef __ANDROID__ |
| /// // On Android, The Java GvrLayout owns the gvr_context. |
| /// #else |
| /// gvr_destroy(gvr); |
| /// #endif |
| /// |
| /// Head tracking is enabled by default, and will begin as soon as the |
| /// gvr_context is created. The client should call gvr_pause_tracking() and |
| /// gvr_resume_tracking() when the app is paused and resumed, respectively. |
| /// |
| /// Note: Unless otherwise noted, the functions in this API may not be |
| /// thread-safe with respect to the gvr_context, and it is up the caller to use |
| /// the API in a thread-safe manner. |
| /// |
| /// @{ |
| |
| /// Creates a new gvr instance. |
| /// |
| /// The instance must remain valid as long as any GVR object is in use. When |
| /// the application no longer needs to use the GVR SDK, call gvr_destroy(). |
| /// |
| /// |
| /// On Android, the gvr_context should *almost always* be obtained from the Java |
| /// GvrLayout object, rather than explicitly created here. The GvrLayout should |
| /// live in the app's View hierarchy, and its use is required to ensure |
| /// consistent behavior across all varieties of GVR-compatible viewers. See |
| /// the Java GvrLayout and GvrApi documentation for more details. |
| /// |
| #ifdef __ANDROID__ |
| /// @param env The JNIEnv associated with the current thread. |
| /// @param app_context The Android application context. This must be the |
| /// application context, NOT an Activity context (Note: from any Android |
| /// Activity in your app, you can call getApplicationContext() to |
| /// retrieve the application context). |
| /// @param class_loader The class loader to use when loading Java classes. |
| /// This must be your app's main class loader (usually accessible through |
| /// activity.getClassLoader() on any of your Activities). |
| /// |
| /// @return Pointer to the created gvr instance, NULL on failure. |
| gvr_context* gvr_create(JNIEnv* env, jobject app_context, jobject class_loader); |
| #else |
| /// @return Pointer to the created gvr instance, NULL on failure. |
| gvr_context* gvr_create(); |
| #endif // #ifdef __ANDROID__ |
| |
| /// Gets the current GVR runtime version. |
| /// |
| /// Note: This runtime version may differ from the version against which the |
| /// client app is compiled, as defined by the semantic version components in |
| /// gvr_version.h. |
| /// |
| /// @return The version as a gvr_version. |
| gvr_version gvr_get_version(); |
| |
| /// Gets a string representation of the current GVR runtime version. This is of |
| /// the form "MAJOR.MINOR.PATCH". |
| /// |
| /// Note: This runtime version may differ from the version against which the |
| /// client app is compiled, as defined in gvr_version.h by |
| /// GVR_SDK_VERSION_STRING. |
| /// |
| /// @return The version as a static char pointer. |
| const char* gvr_get_version_string(); |
| |
| /// Gets the current GVR error code, or GVR_ERROR_NONE if there is no error. |
| /// This function doesn't clear the error code; see gvr_clear_error(). |
| /// |
| /// @param gvr Pointer to the gvr instance. |
| /// @return The current gvr_error code, or GVR_ERROR_NONE if no error has |
| /// occurred. |
| int32_t gvr_get_error(gvr_context* gvr); |
| |
| /// Clears the current GVR error code, and returns the error code that was |
| /// cleared. |
| /// |
| /// @param gvr Pointer to the gvr instance. |
| /// @return The gvr_error code that was cleared by this function, or |
| /// GVR_ERROR_NONE if no error has occurred. |
| int32_t gvr_clear_error(gvr_context* gvr); |
| |
| /// Gets a human-readable string representing the given error code. |
| /// |
| /// @param error_code The gvr_error code. |
| /// @return A human-readable string representing the error code. |
| const char* gvr_get_error_string(int32_t error_code); |
| |
| /// Polls the event queue, populating the provided event if available while also |
| /// popping it from the event queue. |
| /// |
| /// Note that it is the caller's responsibility for querying the event queue |
| /// in a timely fashion, as it will otherwise be flushed periodically. |
| /// |
| /// @param gvr_context The current context. |
| /// @param event_out The event to populate. This will be populated with a valid |
| /// gvr_event iff the result is GVR_NO_ERROR. |
| /// @return GVR_ERROR_NONE if an event was available, otherwise |
| /// GVR_ERROR_NO_EVENT_AVAILABLE. |
| int32_t gvr_poll_event(gvr_context* gvr, gvr_event* event_out); |
| |
| /// Gets a read-only handle to the current global set of GVR-related properties. |
| /// |
| /// @param gvr_context The current context. |
| /// @return gvr_properties An opaque handle to the current, global properties |
| /// instance. Note that this handle is valid only as long as the provided |
| /// context is valid, and must not be used after the context is destroyed. |
| const gvr_properties* gvr_get_current_properties(gvr_context* gvr); |
| |
| /// Queries the given property's value, populating the provided value if |
| /// available. |
| /// |
| /// @param gvr_properties The set of properties to query. |
| /// @param property_key The property being queried. |
| /// @return GVR_ERROR_NONE if the property was available, otherwise |
| /// GVR_ERROR_NO_PROPERTY_AVAILABLE. |
| int32_t gvr_properties_get(const gvr_properties* properties, |
| int32_t property_key, gvr_value* value_out); |
| |
| /// Returns an opaque struct containing information about user preferences. |
| /// |
| /// The returned struct will remain valid as long as the context is valid. |
| /// The returned struct may be updated when the user changes their preferences, |
| /// so this function only needs to be called once, and calling it multiple |
| /// times will return the same object each time. |
| /// |
| /// @param gvr Pointer to the gvr instance. |
| /// @return An opaque struct containing information about user preferences. |
| const gvr_user_prefs* gvr_get_user_prefs(gvr_context* gvr); |
| |
| /// Returns the controller handedness of the given gvr_user_prefs struct. |
| /// |
| /// @param user_prefs Pointer to the gvr_user_prefs object returned by |
| /// gvr_get_user_prefs. |
| /// @return Either GVR_CONTROLLER_RIGHT_HANDED or GVR_CONTROLLER_LEFT_HANDED |
| /// depending on which hand the user holds the controller in. |
| int32_t gvr_user_prefs_get_controller_handedness( |
| const gvr_user_prefs* user_prefs); |
| |
| /// Destroys a gvr_context instance. The parameter will be nulled by this |
| /// operation. Once this function is called, the behavior of any subsequent |
| /// call to a GVR SDK function that references objects created from this |
| /// context is undefined. |
| /// |
| /// @param gvr Pointer to a pointer to the gvr instance to be destroyed and |
| /// nulled. |
| void gvr_destroy(gvr_context** gvr); |
| |
| /// Initializes necessary GL-related objects and uses the current thread and |
| /// GL context for rendering. Please make sure that a valid GL context is |
| /// available when this function is called. |
| /// |
| /// @param gvr Pointer to the gvr instance to be initialized. |
| void gvr_initialize_gl(gvr_context* gvr); |
| |
| /// Gets whether asynchronous reprojection is currently enabled. |
| /// |
| /// If enabled, frames will be collected by the rendering system and |
| /// asynchronously re-projected in sync with the scanout of the display. This |
| /// feature may not be available on every platform, and requires a |
| /// high-priority render thread with special extensions to function properly. |
| /// |
| /// Note: On Android, this feature can be enabled solely via the GvrLayout Java |
| /// instance which (indirectly) owns this gvr_context. The corresponding |
| /// method call is GvrLayout.setAsyncReprojectionEnabled(). |
| /// |
| /// Note: Because of the above requirements, asynchronous reprojection is only |
| /// currently available on Daydream-ready Android devices. This function will |
| /// always return false on other devices. |
| /// |
| /// @param gvr Pointer to the gvr instance. |
| /// @return Whether async reprojection is enabled. Defaults to false. |
| bool gvr_get_async_reprojection_enabled(const gvr_context* gvr); |
| |
| /// Gets the recommended buffer viewport configuration, populating a previously |
| /// allocated gvr_buffer_viewport_list object. The updated values include the |
| /// per-eye recommended viewport and field of view for the target. |
| /// |
| /// When the recommended viewports are used for distortion rendering, this |
| /// method should always be called after calling refresh_viewer_profile(). That |
| /// will ensure that the populated viewports reflect the currently paired |
| /// viewer. |
| /// |
| /// This function assumes that the client is *not* using multiview to render to |
| /// multiple layers simultaneously. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the viewports. |
| /// @param viewport_list Pointer to a previously allocated viewport list. This |
| /// will be populated with the recommended buffer viewports and resized if |
| /// necessary. |
| void gvr_get_recommended_buffer_viewports( |
| const gvr_context* gvr, gvr_buffer_viewport_list* viewport_list); |
| |
| /// Gets the screen (non-distorted) buffer viewport configuration, populating a |
| /// previously allocated gvr_buffer_viewport_list object. The updated values |
| /// include the per-eye recommended viewport and field of view for the target. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the viewports. |
| /// @param viewport_list Pointer to a previously allocated viewport list. This |
| /// will be populated with the screen buffer viewports and resized if |
| /// necessary. |
| void gvr_get_screen_buffer_viewports(const gvr_context* gvr, |
| gvr_buffer_viewport_list* viewport_list); |
| |
| /// Returns the maximum effective size for the client's render target, given the |
| /// parameters of the head mounted device selected. At this resolution, we have |
| /// a 1:1 ratio between source pixels and screen pixels in the most magnified |
| /// region of the screen. Applications should rarely, if ever, need to render |
| /// to a larger target, as it will simply result in sampling artifacts. |
| /// |
| /// Note that this is probably too large for most applications to use as a |
| /// render target size. Applications should scale this value to be appropriate |
| /// to their graphical load. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the size. |
| /// |
| /// @return Maximum effective size for the target render target. |
| gvr_sizei gvr_get_maximum_effective_render_target_size(const gvr_context* gvr); |
| |
| /// Returns a non-distorted size for the screen, given the parameters |
| /// of the phone and/or the head mounted device selected. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the size. |
| /// |
| /// @return Screen (non-distorted) size for the render target. |
| gvr_sizei gvr_get_screen_target_size(const gvr_context* gvr); |
| |
| // Sets the size of the underlying render surface. |
| // |
| // By default, it is assumed that the display size matches the surface |
| // size. If that is the case for the client app, this method need never be |
| // called. However, in certain cases (e.g., hardware scaling), this will not |
| // always hold, in which case the distortion pass must be informed of the |
| // custom surface size. |
| // |
| // Note that the caller is responsible for resizing any BufferSpec objects |
| // created before this function is called. Otherwise there will be rendering |
| // artifacts, such as edges appearing pixelated. This function will change the |
| // result of get_maximum_effective_render_target_size(), so that function can be |
| // used to compute the appropriate size for buffers. |
| // |
| // @param gvr Pointer to the gvr_context instance. |
| // @param surface_size_pixels The size in pixels of the display surface. If |
| // non-empty, this will be used in conjunction with the current display to |
| // perform properly scaled distortion. If empty, it is assumed that the |
| // rendering surface dimensions match that of the active display. |
| void gvr_set_surface_size(gvr_context* gvr, gvr_sizei surface_size_pixels); |
| |
| /// @deprecated Use the Swap Chain API instead. This function exists only to |
| /// support legacy rendering pathways for Cardboard devices. It is |
| /// incompatible with the low-latency experiences supported by async |
| /// reprojection. |
| /// |
| /// Performs postprocessing, including lens distortion, on the contents of the |
| /// passed texture and shows the result on the screen. Lens distortion is |
| /// determined by the parameters of the viewer encoded in its QR code. The |
| /// passed texture is not modified. |
| /// |
| /// If the application does not call gvr_initialize_gl() before calling this |
| /// function, the results are undefined. |
| /// |
| /// @param gvr Pointer to the gvr instance which will do the distortion. |
| /// @param texture_id The OpenGL ID of the texture that contains the next frame |
| /// to be displayed. |
| /// @param viewport_list Rendering parameters. |
| /// @param head_space_from_start_space This parameter is ignored. |
| /// @param target_presentation_time This parameter is ignored. |
| void gvr_distort_to_screen(gvr_context* gvr, int32_t texture_id, |
| const gvr_buffer_viewport_list* viewport_list, |
| gvr_mat4f head_space_from_start_space, |
| gvr_clock_time_point target_presentation_time); |
| |
| /// Queries whether a particular GVR feature is supported by the underlying |
| /// platform. This should be called after gvr_initialize_gl(). |
| /// |
| /// @param gvr The context to query against. |
| /// @param feature The gvr_feature type being queried. |
| /// @return true if feature is supported, false otherwise. |
| bool gvr_is_feature_supported(const gvr_context* gvr, int32_t feature); |
| |
| /// @} |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Viewports and viewport lists |
| ///////////////////////////////////////////////////////////////////////////// |
| /// @defgroup viewport Viewports and viewport lists |
| /// @brief Objects to define the mapping between the application's rendering |
| /// output and the user's field of view. |
| /// @{ |
| |
| /// Creates a gvr_buffer_viewport instance. |
| gvr_buffer_viewport* gvr_buffer_viewport_create(gvr_context* gvr); |
| |
| /// Frees a gvr_buffer_viewport instance and clears the pointer. |
| void gvr_buffer_viewport_destroy(gvr_buffer_viewport** viewport); |
| |
| /// Gets the UV coordinates specifying where the output buffer is sampled. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return UV coordinates as a rectangle. |
| gvr_rectf gvr_buffer_viewport_get_source_uv( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the UV coordinates specifying where the output buffer should be |
| /// sampled when compositing the final distorted image. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param uv The new UV coordinates for sampling. The coordinates must be |
| /// valid, that is, left <= right and bottom <= top. Otherwise an empty |
| /// source region is set, which will result in no output for this viewport. |
| void gvr_buffer_viewport_set_source_uv(gvr_buffer_viewport* viewport, |
| gvr_rectf uv); |
| |
| /// Retrieves the field of view for the referenced buffer region. |
| /// |
| /// This is a helper that converts the stored projection matrix to a field of |
| /// view. Note that if the previously set projection matrix cannot be expressed |
| /// as a view frustum aligned with the eye's optical axis, the result will be |
| /// incorrect. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return The field of view of the rendered image, in degrees. |
| gvr_rectf gvr_buffer_viewport_get_source_fov( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the field of view for the viewport contents. |
| /// |
| /// This is a helper that sets the projection matrix in such a way that the |
| /// viewport's contents fill the specified FOV around the eye's optical axis. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param fov The field of view to use when compositing the rendered image, |
| /// in degrees. |
| void gvr_buffer_viewport_set_source_fov(gvr_buffer_viewport* viewport, |
| gvr_rectf fov); |
| |
| /// Gets the matrix that positions the viewport in eye space. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return Matrix that transforms a quad with vertices (-1, -1, 0), (1, -1, 0), |
| /// (-1, 1, 0), (1, 1, 0) representing the viewport contents to its desired |
| /// eye space position for the target eye. |
| gvr_mat4f gvr_buffer_viewport_get_transform( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the matrix that positions the viewport in eye space. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param transform Matrix that transforms a quad with vertices (-1, -1, 0), |
| /// (1, -1, 0), (-1, 1, 0), (1, 1, 0) representing the viewport contents to |
| /// its desired eye space position for the target eye. |
| void gvr_buffer_viewport_set_transform(gvr_buffer_viewport* viewport, |
| gvr_mat4f transform); |
| |
| /// Gets the target logical eye for the specified viewport. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return Index of the target logical eye for this viewport. |
| int32_t gvr_buffer_viewport_get_target_eye(const gvr_buffer_viewport* viewport); |
| |
| /// Sets the target logical eye for the specified viewport. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param index Index of the target logical eye. |
| void gvr_buffer_viewport_set_target_eye(gvr_buffer_viewport* viewport, |
| int32_t index); |
| |
| /// Gets the index of the source buffer from which the viewport reads its |
| /// undistorted pixels. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return Index of the source buffer. This corresponds to the index in the |
| /// list of buffer specs that was passed to gvr_swap_chain_create(). |
| int32_t gvr_buffer_viewport_get_source_buffer_index( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the buffer from which the viewport reads its undistorted pixels. |
| /// |
| /// To use the contents of the external surface as buffer contents, associate an |
| /// external surface with the viewport by calling |
| /// gvr_buffer_viewport_set_external_surface_id(), then call this function and |
| /// pass GVR_BUFFER_INDEX_EXTERNAL_SURFACE. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param buffer_index The index of the source buffer. This is either an index |
| /// in the list of buffer specs that was passed to |
| /// gvr_swap_chain_create(), or GVR_BUFFER_INDEX_EXTERNAL_SURFACE. |
| void gvr_buffer_viewport_set_source_buffer_index( |
| gvr_buffer_viewport* viewport, int32_t buffer_index); |
| |
| /// Gets the ID of the externally-managed Surface texture from which this |
| /// viewport reads undistored pixels. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return ID of the externally-managed Surface of undistorted pixels. |
| int32_t gvr_buffer_viewport_get_external_surface_id( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the ID of the externally-managed Surface texture from which this |
| /// viewport reads. The ID is issued by GvrLayout. If this viewport does not |
| /// read from an external surface, this should be set to |
| /// GVR_EXTERNAL_SURFACE_ID_NONE, which is also the default value. If it does |
| /// read from an external surface, set this to the ID obtained from GvrLayout |
| /// and set the source buffer index to the special value |
| /// GVR_BUFFER_INDEX_EXTERNAL_SURFACE. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param external_surface_id The ID of the surface to read from. |
| void gvr_buffer_viewport_set_external_surface_id( |
| gvr_buffer_viewport* viewport, int32_t external_surface_id); |
| |
| /// Gets the type of reprojection to perform on the specified viewport. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return Type of reprojection that is applied to the viewport. |
| int32_t gvr_buffer_viewport_get_reprojection( |
| const gvr_buffer_viewport* viewport); |
| |
| /// Sets the type of reprojection to perform on the specified viewport. |
| /// Viewports that display world content should use full reprojection. |
| /// Viewports that display head-locked UI should disable reprojection to avoid |
| /// excessive judder. The default is to perform full reprojection. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param reprojection Type of reprojection that will be applied to the passed |
| /// viewport. |
| void gvr_buffer_viewport_set_reprojection(gvr_buffer_viewport* viewport, |
| int32_t reprojection); |
| |
| /// Sets the layer in a multiview buffer from which the viewport should sample. |
| /// |
| /// @param layer_index The layer in the array texture that distortion samples |
| /// from. Must be non-negative. Defaults to 0. |
| void gvr_buffer_viewport_set_source_layer(gvr_buffer_viewport* viewport, |
| int32_t layer_index); |
| |
| /// Gets the opacity to perform on the specified viewport. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @return opacity that is applied to the viewport, default to be 1. |
| float gvr_buffer_viewport_get_opacity(const gvr_buffer_viewport* viewport); |
| |
| /// Sets the opacity to perform on the specified viewport. |
| /// |
| /// @param viewport The buffer viewport. |
| /// @param opacity Opacity that will be applied per viewport. |
| /// It should be within [0,1], default to be 1. |
| void gvr_buffer_viewport_set_opacity(gvr_buffer_viewport* viewport, |
| float opacity); |
| |
| /// Compares two gvr_buffer_viewport instances and returns true if they specify |
| /// the same view mapping. |
| /// |
| /// @param a Instance of a buffer viewport. |
| /// @param b Another instance of a buffer viewport. |
| /// @return True if the passed viewports are the same. |
| bool gvr_buffer_viewport_equal(const gvr_buffer_viewport* a, |
| const gvr_buffer_viewport* b); |
| |
| /// Creates a new, empty list of viewports. The viewport list defines how the |
| /// application's rendering output should be transformed into the stabilized, |
| /// lens-distorted image that is sent to the screen. |
| /// |
| /// The caller should populate the returned viewport using one of: |
| /// - gvr_get_recommended_buffer_viewports() |
| /// - gvr_get_screen_buffer_viewports() |
| /// - gvr_buffer_viewport_list_set_item() |
| /// |
| /// @param gvr Pointer the gvr instance from which to allocate the viewport |
| /// list. |
| /// @return Pointer to an allocated gvr_buffer_viewport_list object. The caller |
| // is responsible for calling gvr_buffer_viewport_list_destroy() on the |
| /// returned object when it is no longer needed. |
| gvr_buffer_viewport_list* gvr_buffer_viewport_list_create( |
| const gvr_context* gvr); |
| |
| /// Destroys a gvr_buffer_viewport_list instance. The parameter will be nulled |
| /// by this operation. |
| /// |
| /// @param viewport_list Pointer to a pointer to the viewport list instance to |
| /// be destroyed and nulled. |
| void gvr_buffer_viewport_list_destroy(gvr_buffer_viewport_list** viewport_list); |
| |
| /// Returns the size of the given viewport list. |
| /// |
| /// @param viewport_list Pointer to a viewport list. |
| /// @return The number of entries in the viewport list. |
| size_t gvr_buffer_viewport_list_get_size( |
| const gvr_buffer_viewport_list* viewport_list); |
| |
| /// Retrieve a buffer viewport entry from a list. |
| /// |
| /// @param viewport_list Pointer to the previously allocated viewport list. |
| /// @param index Zero-based index of the viewport entry to query. Must be |
| /// smaller than the list size. |
| /// @param viewport The buffer viewport structure that will be populated with |
| /// retrieved data. |
| void gvr_buffer_viewport_list_get_item( |
| const gvr_buffer_viewport_list* viewport_list, size_t index, |
| gvr_buffer_viewport* viewport); |
| |
| /// Update an element of the viewport list or append a new one at the end. |
| /// |
| /// @param viewport_list Pointer to a previously allocated viewport list. |
| /// @param index Index of the buffer viewport entry to update. If the |
| /// `viewport_list` size is equal to the index, a new viewport entry will be |
| /// added. The `viewport_list` size must *not* be less than the index value. |
| /// @param viewport A pointer to the buffer viewport object. |
| void gvr_buffer_viewport_list_set_item(gvr_buffer_viewport_list* viewport_list, |
| size_t index, |
| const gvr_buffer_viewport* viewport); |
| |
| /// @} |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Swapchains and frames |
| ///////////////////////////////////////////////////////////////////////////// |
| /// @defgroup swap_chain Swap chains and frames |
| /// @brief Functions to create a swap chain, manipulate it and submit frames |
| /// for lens distortion and presentation on the screen. |
| /// @{ |
| |
| /// Creates a default buffer specification. |
| gvr_buffer_spec* gvr_buffer_spec_create(gvr_context* gvr); |
| |
| /// Destroy the buffer specification and null the pointer. |
| void gvr_buffer_spec_destroy(gvr_buffer_spec** spec); |
| |
| /// Gets the size of the buffer to be created. |
| /// |
| /// @param spec Buffer specification. |
| /// @return Size of the pixel buffer. The default is equal to the recommended |
| /// render target size at the time when the specification was created. |
| gvr_sizei gvr_buffer_spec_get_size(const gvr_buffer_spec* spec); |
| |
| /// Sets the size of the buffer to be created. |
| /// |
| /// @param spec Buffer specification. |
| /// @param size The size. Width and height must both be greater than zero. |
| /// Otherwise, the application is aborted. |
| void gvr_buffer_spec_set_size(gvr_buffer_spec* spec, gvr_sizei size); |
| |
| /// Gets the number of samples per pixel in the buffer to be created. |
| /// |
| /// @param spec Buffer specification. |
| /// @return Value >= 1 giving the number of samples. 1 means multisampling is |
| /// disabled. Negative values and 0 are never returned. |
| int32_t gvr_buffer_spec_get_samples(const gvr_buffer_spec* spec); |
| |
| /// Sets the number of samples per pixel in the buffer to be created. |
| /// |
| /// @param spec Buffer specification. |
| /// @param num_samples The number of samples. Negative values are an error. |
| /// The values 0 and 1 are treated identically and indicate that |
| // multisampling should be disabled. |
| void gvr_buffer_spec_set_samples(gvr_buffer_spec* spec, int32_t num_samples); |
| |
| /// Sets the color format for the buffer to be created. Default format is |
| /// GVR_COLOR_FORMAT_RGBA_8888. For all alpha-containing formats, the pixels |
| /// are expected to be premultiplied with alpha. In other words, the 60% opaque |
| /// primary green color is (0.0, 0.6, 0.0, 0.6). |
| /// |
| /// @param spec Buffer specification. |
| /// @param color_format The color format for the buffer. Valid formats are in |
| /// the gvr_color_format_type enum. |
| void gvr_buffer_spec_set_color_format(gvr_buffer_spec* spec, |
| int32_t color_format); |
| |
| /// Sets the depth and stencil format for the buffer to be created. Currently, |
| /// only packed stencil formats are supported. Default format is |
| /// GVR_DEPTH_STENCIL_FORMAT_DEPTH_16. |
| /// |
| /// @param spec Buffer specification. |
| /// @param depth_stencil_format The depth and stencil format for the buffer. |
| /// Valid formats are in the gvr_depth_stencil_format_type enum. |
| void gvr_buffer_spec_set_depth_stencil_format(gvr_buffer_spec* spec, |
| int32_t depth_stencil_format); |
| |
| /// Sets the number of layers in a framebuffer backed by an array texture. |
| /// |
| /// Default is 1, which means a non-layered texture will be created. |
| /// Not all platforms support multiple layers, so clients can call |
| /// gvr_is_feature_supported(GVR_FEATURE_MULTIVIEW) to check. |
| /// |
| /// @param spec Buffer specification. |
| /// @param num_layers The number of layers in the array texture. |
| void gvr_buffer_spec_set_multiview_layers(gvr_buffer_spec* spec, |
| int32_t num_layers); |
| |
| /// Creates a swap chain from the given buffer specifications. |
| /// This is a potentially time-consuming operation. All frames within the |
| /// swapchain will be allocated. Once rendering is stopped, call |
| /// gvr_swap_chain_destroy() to free GPU resources. The passed gvr_context must |
| /// not be destroyed until then. |
| /// |
| /// Swap chains can have no buffers. This is useful when only displaying |
| /// external surfaces. When `count` is zero, `buffers` must be null. |
| /// |
| /// @param gvr GVR instance for which a swap chain will be created. |
| /// @param buffers Array of pixel buffer specifications. Each frame in the |
| /// swap chain will be composed of these buffers. |
| /// @param count Number of buffer specifications in the array. |
| /// @return Opaque handle to the newly created swap chain. |
| gvr_swap_chain* gvr_swap_chain_create(gvr_context* gvr, |
| const gvr_buffer_spec** buffers, |
| int32_t count); |
| |
| /// Destroys the swap chain and nulls the pointer that is passed in. This |
| /// should be called after rendering is finished to free all the buffers that |
| /// have been allocated in the swap chain. |
| /// |
| /// @param swap_chain The swap chain to destroy. |
| void gvr_swap_chain_destroy(gvr_swap_chain** swap_chain); |
| |
| /// Gets the number of buffers in each frame of the swap chain. |
| /// |
| /// @param swap_chain The swap chain to query. |
| /// @return The number of buffers in the swap chain. |
| int32_t gvr_swap_chain_get_buffer_count(const gvr_swap_chain* swap_chain); |
| |
| /// Retrieves the size of the specified pixel buffer. Note that if the buffer |
| /// was resized while the current frame was acquired, the return value will be |
| /// different than the value obtained from the equivalent function for the |
| /// current frame. |
| /// |
| /// @param swap_chain The swap chain. |
| /// @param index Index of the pixel buffer. |
| /// @return Size of the specified pixel buffer in frames that will be returned |
| /// from gvr_swap_chain_acquire_frame(). |
| gvr_sizei gvr_swap_chain_get_buffer_size(const gvr_swap_chain* swap_chain, |
| int32_t index); |
| |
| /// Resizes the specified pixel buffer to the given size. The frames are resized |
| /// when they are unused, so the currently acquired frame will not be resized |
| /// immediately. |
| /// |
| /// @param swap_chain The swap chain. |
| /// @param index Index of the pixel buffer to resize. |
| /// @param size New size for the specified pixel buffer. |
| void gvr_swap_chain_resize_buffer(gvr_swap_chain* swap_chain, int32_t index, |
| gvr_sizei size); |
| |
| /// Acquires a frame from the swap chain for rendering. Buffers that are part of |
| /// the frame can then be bound with gvr_frame_bind_buffer(). Once the frame |
| /// is finished and all its constituent buffers are ready, call |
| /// gvr_frame_submit() to display it while applying lens distortion. |
| /// |
| /// When this is called, the current thread's GL context must be the same |
| /// context that was current when gvr_initialize_gl() was called, or at least be |
| /// in a share group with the initialization context. |
| /// |
| /// @param swap_chain The swap chain. |
| /// @return Handle to the acquired frame. NULL if the swap chain is invalid, |
| /// or if acquire has already been called on this swap chain. |
| gvr_frame* gvr_swap_chain_acquire_frame(gvr_swap_chain* swap_chain); |
| |
| /// Binds a pixel buffer that is part of the frame to the OpenGL framebuffer. |
| /// |
| /// @param frame Frame handle acquired from the swap chain. |
| /// @param index Index of the pixel buffer to bind. This corresponds to the |
| /// index in the buffer spec list that was passed to |
| /// gvr_swap_chain_create(). |
| void gvr_frame_bind_buffer(gvr_frame* frame, int32_t index); |
| |
| /// Unbinds any buffers bound from this frame and binds the default OpenGL |
| /// framebuffer. |
| void gvr_frame_unbind(gvr_frame* frame); |
| |
| /// Returns the dimensions of the pixel buffer with the specified index. Note |
| /// that a frame that was acquired before resizing a swap chain buffer will not |
| /// be resized until it is submitted to the swap chain. |
| /// |
| /// @param frame Frame handle. |
| /// @param index Index of the pixel buffer to inspect. |
| /// @return Dimensions of the specified pixel buffer. |
| gvr_sizei gvr_frame_get_buffer_size(const gvr_frame* frame, int32_t index); |
| |
| /// Gets the name (ID) of the framebuffer object associated with the specified |
| /// buffer. The OpenGL state is not modified. |
| /// |
| /// @param frame Frame handle. |
| /// @param index Index of a pixel buffer. |
| /// @return OpenGL object name (ID) of a framebuffer object which can be used |
| /// to render into the buffer. The ID is valid only until the frame is |
| /// submitted. |
| int32_t gvr_frame_get_framebuffer_object(const gvr_frame* frame, int32_t index); |
| |
| /// Gets the hardware buffer backing the specified frame buffer. |
| /// |
| /// Hardware buffers (Android NDK type AHardwareBuffer) are used to back frames |
| /// if asynchronous reprojection is enabled and GVR_FEATURE_HARDWARE_BUFFERS is |
| /// supported (currently on Android O and later Android versions). See the |
| /// documentation for the feature enum value for further information. |
| /// |
| /// There is no need to acquire or release the AHardwareBuffer. The swap chain |
| /// maintains a reference to it while the frame is acquired. |
| /// |
| /// @param frame The gvr_frame from which to obtain the buffer. |
| /// @param index Index of the pixel buffer. |
| /// @return Pointer to AHardwareBuffer backing the frame's pixel buffer where |
| /// available, or NULL otherwise. |
| AHardwareBuffer* gvr_frame_get_hardware_buffer(const gvr_frame* frame, |
| int32_t index); |
| |
| /// Submits the frame for distortion and display on the screen. The passed |
| /// pointer is nulled to prevent reuse. |
| /// |
| /// Note: On Cardboard devices, this function makes OpenGL commands in the |
| /// current thread's GL context; this can affect various GL state such as |
| /// texture bindings, depth testing, backface culling, and blending. |
| /// |
| /// @param frame The frame to submit. |
| /// @param list Buffer view configuration to be used for this frame. |
| /// @param head_space_from_start_space Transform from start space (space with |
| /// head at the origin at last tracking reset) to head space (space with |
| /// head at the origin and axes aligned to the view vector). |
| void gvr_frame_submit(gvr_frame** frame, const gvr_buffer_viewport_list* list, |
| gvr_mat4f head_space_from_start_space); |
| |
| /// Resets the OpenGL framebuffer binding to what it was at the time the |
| /// passed gvr_context was created. |
| void gvr_bind_default_framebuffer(gvr_context* gvr); |
| |
| /// @} |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Head tracking |
| ///////////////////////////////////////////////////////////////////////////// |
| /// @defgroup Headtracking Head tracking |
| /// @brief Functions for managing head tracking. |
| /// @{ |
| |
| /// Gets the current monotonic system time. |
| /// |
| /// @return The current monotonic system time. |
| gvr_clock_time_point gvr_get_time_point_now(); |
| |
| /// @deprecated Calls to this method can be safely replaced by calls to |
| /// gvr_get_head_space_from_start_space_transform. The new API reflects that |
| /// the call *can* return a full 6DoF transform when supported by both the |
| /// host platform and the client application. |
| /// |
| /// Gets the rotation from start space to head space. The head space is a |
| /// space where the head is at the origin and faces the -Z direction. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the pose. |
| /// @param time The time at which to get the head pose. The time should be in |
| /// the future. If the time is not in the future, it will be clamped to now. |
| /// @return A matrix representation of the rotation from start space (the space |
| /// where the head was last reset) to head space (the space with the head |
| /// at the origin, and the axes aligned to the view vector). |
| gvr_mat4f gvr_get_head_space_from_start_space_rotation( |
| const gvr_context* gvr, const gvr_clock_time_point time); |
| |
| /// Gets the position and rotation from start space to head space. The head |
| /// space is a space where the head is at the origin and faces the -Z direction. |
| /// |
| /// For platforms that support 6DoF head tracking, the app may also be required |
| /// to declare support for 6DoF in order to receive a fully formed 6DoF pose, |
| /// e.g., on Android, this requires declaration of support for at least version |
| /// 1 of the "android.hardware.vr.headtracking" feature in the manifest. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the pose. |
| /// @param time The time at which to get the head pose. The time should be in |
| /// the future. If the time is not in the future, it will be clamped to now. |
| /// @return A matrix representation of the position and rotation from start |
| /// space (the space where the head was last reset) to head space (the |
| /// space with the head at the origin, and the axes aligned to the view |
| /// vector). |
| gvr_mat4f gvr_get_head_space_from_start_space_transform( |
| const gvr_context* gvr, const gvr_clock_time_point time); |
| |
| /// Applies a simple neck model translation based on the rotation of the |
| /// provided head pose. |
| /// |
| /// Note: Neck model application may not be appropriate for all tracking |
| /// scenarios, e.g., when tracking is non-biological. |
| /// |
| /// @param gvr Pointer to the context instance from which the pose was obtained. |
| /// @param head_space_from_start_space_rotation The head rotation as returned by |
| /// gvr_get_head_space_from_start_space_rotation(). |
| /// @param factor A scaling factor for the neck model offset, clamped from 0 to |
| /// 1. This should be 1 for most scenarios, while 0 will effectively disable |
| /// neck model application. This value can be animated to smoothly |
| /// interpolate between alternative (client-defined) neck models. |
| /// @return The new head pose with the neck model applied. |
| gvr_mat4f gvr_apply_neck_model(const gvr_context* gvr, |
| gvr_mat4f head_space_from_start_space_rotation, |
| float factor); |
| |
| /// Pauses head tracking, disables all sensors (to save power). |
| /// |
| /// @param gvr Pointer to the gvr instance for which tracking will be paused and |
| /// sensors disabled. |
| void gvr_pause_tracking(gvr_context* gvr); |
| |
| /// Resumes head tracking, re-enables all sensors. |
| /// |
| /// @param gvr Pointer to the gvr instance for which tracking will be resumed. |
| void gvr_resume_tracking(gvr_context* gvr); |
| |
| /// @deprecated Calls to this method can be safely replaced by calls to |
| /// gvr_recenter_tracking. This accomplishes the same effects but avoids the |
| /// undesirable side-effects of a full reset (temporary loss of tracking |
| /// quality). |
| /// |
| /// Resets head tracking. |
| /// |
| /// Only to be used by Cardboard apps. Daydream apps must not call this. On the |
| /// Daydream platform, recentering is handled automatically and should never |
| /// be triggered programmatically by applications. Hybrid apps that support both |
| /// Cardboard and Daydream must only call this function when in Cardboard mode |
| /// (that is, when the phone is paired with a Cardboard viewer), never in |
| /// Daydream mode. |
| /// |
| /// @param gvr Pointer to the gvr instance for which tracking will be reseted. |
| void gvr_reset_tracking(gvr_context* gvr); |
| |
| /// Recenters the head orientation (resets the yaw to zero, leaving pitch and |
| /// roll unmodified). |
| /// |
| /// Only to be used by Cardboard apps. Daydream apps must not call this. On the |
| /// Daydream platform, recentering is handled automatically and should never |
| /// be triggered programmatically by applications. Hybrid apps that support both |
| /// Cardboard and Daydream must only call this function when in Cardboard mode |
| /// (that is, when the phone is paired with a Cardboard viewer), never in |
| /// Daydream mode. |
| /// |
| /// @param gvr Pointer to the gvr instance for which tracking will be |
| /// recentered. |
| void gvr_recenter_tracking(gvr_context* gvr); |
| |
| /// @} |
| |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Head mounted display. |
| ///////////////////////////////////////////////////////////////////////////// |
| /// @defgroup HMD Head Mounted Display |
| /// @brief Functions for managing viewer information. |
| /// @{ |
| |
| /// Sets the default viewer profile specified by viewer_profile_uri. |
| /// The viewer_profile_uri that is passed in will be ignored if a valid |
| /// viewer profile has already been stored on the device that the app |
| /// is running on. |
| /// |
| /// Note: This function has the potential of blocking for up to 30 seconds for |
| /// each redirect if a shortened URI is passed in as argument. It will try to |
| /// unroll the shortened URI for a maximum number of 5 times if the redirect |
| /// continues. In that case, it is recommended to create a separate thread to |
| /// call this function so that other tasks like rendering will not be blocked |
| /// on this. The blocking can be avoided if a standard URI is passed in. |
| /// |
| /// @param gvr Pointer to the gvr instance which to set the profile on. |
| /// @param viewer_profile_uri A string that contains either the shortened URI or |
| /// the standard URI representing the viewer profile that the app should be |
| /// using. If the valid viewer profile can be found on the device, the URI |
| /// that is passed in will be ignored and nothing will happen. Otherwise, |
| /// gvr will look for the viewer profile specified by viewer_profile_uri, |
| /// and it will be stored if found. Also, the values will be applied to gvr. |
| /// A valid standard URI can be generated from this page: |
| /// https://www.google.com/get/cardboard/viewerprofilegenerator/ |
| /// @return True if the viewer profile specified by viewer_profile_uri was |
| /// successfully stored and applied, false otherwise. |
| bool gvr_set_default_viewer_profile(gvr_context* gvr, |
| const char* viewer_profile_uri); |
| |
| /// Refreshes gvr_context with the viewer profile that is stored on the device. |
| /// If it can not find the viewer profile, nothing will happen. |
| /// |
| /// @param gvr Pointer to the gvr instance to refresh the profile on. |
| void gvr_refresh_viewer_profile(gvr_context* gvr); |
| |
| /// Gets the name of the viewer vendor. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the vendor. |
| /// @return A pointer to the vendor name. May be NULL if no viewer is paired. |
| /// WARNING: This method guarantees the validity of the returned pointer |
| /// only until the next use of the `gvr` context. The string should be |
| /// copied immediately if persistence is required. |
| const char* gvr_get_viewer_vendor(const gvr_context* gvr); |
| |
| /// Gets the name of the viewer model. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the name. |
| /// @return A pointer to the model name. May be NULL if no viewer is paired. |
| /// WARNING: This method guarantees the validity of the returned pointer |
| /// only until the next use of the `gvr` context. The string should be |
| /// copied immediately if persistence is required. |
| const char* gvr_get_viewer_model(const gvr_context* gvr); |
| |
| /// Gets the type of the viewer, as defined by gvr_viewer_type. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the viewer type. |
| /// @return The gvr_viewer_type of the currently paired viewer. |
| int32_t gvr_get_viewer_type(const gvr_context* gvr); |
| |
| /// Gets the transformation matrix to convert from Head Space to Eye Space for |
| /// the given eye. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the matrix. |
| /// @param eye Selected eye type. |
| /// @return Transformation matrix from Head Space to selected Eye Space. |
| gvr_mat4f gvr_get_eye_from_head_matrix(const gvr_context* gvr, |
| const int32_t eye); |
| |
| /// Gets the window bounds. |
| /// |
| /// @param gvr Pointer to the gvr instance from which to get the bounds. |
| /// |
| /// @return Window bounds in physical pixels. |
| gvr_recti gvr_get_window_bounds(const gvr_context* gvr); |
| |
| /// Computes the distorted point for a given point in a given eye. The |
| /// distortion inverts the optical distortion caused by the lens for the eye. |
| /// Due to chromatic aberration, the distortion is different for each |
| /// color channel. |
| /// |
| /// @param gvr Pointer to the gvr instance which will do the computing. |
| /// @param eye The gvr_eye type (left or right). |
| /// @param uv_in A point in screen eye Viewport Space in [0,1]^2 with (0, 0) |
| /// in the lower left corner of the eye's viewport and (1, 1) in the |
| /// upper right corner of the eye's viewport. |
| /// @param uv_out A pointer to an array of (at least) 3 elements, with each |
| /// element being a Point2f representing a point in render texture eye |
| /// Viewport Space in [0,1]^2 with (0, 0) in the lower left corner of the |
| /// eye's viewport and (1, 1) in the upper right corner of the eye's |
| /// viewport. |
| /// `uv_out[0]` is the corrected position of `uv_in` for the red channel |
| /// `uv_out[1]` is the corrected position of `uv_in` for the green channel |
| /// `uv_out[2]` is the corrected position of `uv_in` for the blue channel |
| void gvr_compute_distorted_point(const gvr_context* gvr, const int32_t eye, |
| const gvr_vec2f uv_in, gvr_vec2f uv_out[3]); |
| |
| /// @} |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER) |
| namespace gvr { |
| |
| class GvrApi; |
| |
| /// Convenience C++ wrapper for gvr_user_prefs. |
| class UserPrefs : public WrapperBase<const gvr_user_prefs> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// For more information, see gvr_user_prefs_get_controller_handedness(). |
| ControllerHandedness GetControllerHandedness() const { |
| return static_cast<ControllerHandedness>( |
| gvr_user_prefs_get_controller_handedness(cobj())); |
| } |
| }; |
| |
| /// Convenience C++ wrapper for gvr_properties. |
| class Properties : public WrapperBase<const gvr_properties> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// For more information, see gvr_properties_get(). |
| bool Get(int32_t property_key, Value* value_out) const { |
| return gvr_properties_get(cobj(), property_key, value_out) == |
| GVR_ERROR_NONE; |
| } |
| }; |
| |
| /// Convenience C++ wrapper for the opaque gvr_buffer_viewport type. |
| /// The constructor allocates memory, so when used in tight loops, instances |
| /// should be reused. |
| class BufferViewport |
| : public WrapperBase<gvr_buffer_viewport, gvr_buffer_viewport_destroy> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// For more information, see gvr_buffer_viewport_get_source_fov(). |
| Rectf GetSourceFov() const { |
| return gvr_buffer_viewport_get_source_fov(cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_source_fov(). |
| void SetSourceFov(const Rectf& fov) { |
| gvr_buffer_viewport_set_source_fov(cobj(), fov); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_transform(). |
| Mat4f GetTransform() const { |
| return gvr_buffer_viewport_get_transform(cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_transform(). |
| void SetTransform(const Mat4f& transform) { |
| gvr_buffer_viewport_set_transform(cobj(), transform); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_source_uv(). |
| Rectf GetSourceUv() const { |
| return gvr_buffer_viewport_get_source_uv(cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_source_uv(). |
| void SetSourceUv(const Rectf& uv) { |
| gvr_buffer_viewport_set_source_uv(cobj(), uv); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_target_eye(). |
| Eye GetTargetEye() const { |
| return static_cast<Eye>(gvr_buffer_viewport_get_target_eye(cobj())); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_target_eye(). |
| void SetTargetEye(Eye eye) { |
| gvr_buffer_viewport_set_target_eye(cobj(), eye); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_source_buffer_index(). |
| int32_t GetSourceBufferIndex() const { |
| return gvr_buffer_viewport_get_source_buffer_index(cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_source_buffer_index(). |
| void SetSourceBufferIndex(int32_t buffer_index) { |
| gvr_buffer_viewport_set_source_buffer_index(cobj(), buffer_index); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_external_surface_id(). |
| int32_t GetExternalSurfaceId() const { |
| return gvr_buffer_viewport_get_external_surface_id(cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_external_surface_id(). |
| void SetExternalSurfaceId(const int32_t external_surface_id) { |
| gvr_buffer_viewport_set_external_surface_id(cobj(), external_surface_id); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_reprojection(). |
| gvr_reprojection GetReprojection() const { |
| return static_cast<gvr_reprojection>( |
| gvr_buffer_viewport_get_reprojection(cobj())); |
| } |
| /// For more information, see gvr_buffer_viewport_set_reprojection(). |
| void SetReprojection(gvr_reprojection reprojection) { |
| gvr_buffer_viewport_set_reprojection(cobj(), reprojection); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_set_source_layer(). |
| void SetSourceLayer(int32_t layer_index) { |
| gvr_buffer_viewport_set_source_layer(cobj(), layer_index); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_get_opacity(). |
| float GetOpacity() const { return gvr_buffer_viewport_get_opacity(cobj()); } |
| |
| /// For more information, see gvr_buffer_viewport_set_opacity(). |
| void SetOpacity(float opacity) { |
| gvr_buffer_viewport_set_opacity(cobj(), opacity); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_equal(). |
| bool operator==(const BufferViewport& other) const { |
| return gvr_buffer_viewport_equal(cobj(), other.cobj()) ? true : false; |
| } |
| bool operator!=(const BufferViewport& other) const { |
| return !(*this == other); |
| } |
| }; |
| |
| /// Convenience C++ wrapper for the opaque gvr_buffer_viewport_list type. This |
| /// class will automatically release the wrapped gvr_buffer_viewport_list upon |
| /// destruction. It can only be created via a `GvrApi` instance, and its |
| /// validity is tied to the lifetime of that instance. |
| class BufferViewportList |
| : public WrapperBase<gvr_buffer_viewport_list, |
| gvr_buffer_viewport_list_destroy> { |
| public: |
| BufferViewportList() |
| : WrapperBase(nullptr), context_(nullptr) {} |
| |
| BufferViewportList(BufferViewportList&& other) |
| : WrapperBase(nullptr), context_(nullptr) { |
| std::swap(cobject_, other.cobject_); |
| std::swap(context_, other.context_); |
| } |
| |
| BufferViewportList& operator=(BufferViewportList&& other) { |
| std::swap(cobject_, other.cobject_); |
| std::swap(context_, other.context_); |
| return *this; |
| } |
| |
| /// For more information, see gvr_get_recommended_buffer_viewports(). |
| void SetToRecommendedBufferViewports() { |
| gvr_get_recommended_buffer_viewports(context_, cobj()); |
| } |
| |
| /// For more information, see gvr_get_screen_buffer_viewports(). |
| void SetToScreenBufferViewports() { |
| gvr_get_screen_buffer_viewports(context_, cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_list_set_item(). |
| void SetBufferViewport(size_t index, const BufferViewport& viewport) { |
| gvr_buffer_viewport_list_set_item(cobj(), index, |
| viewport.cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_list_get_item(). |
| /// N.B. If *viewport is an empty BufferViewport object, this |
| /// function will initialize it. |
| void GetBufferViewport(size_t index, BufferViewport* viewport) const { |
| if (!*viewport) { |
| *viewport = BufferViewport(gvr_buffer_viewport_create(context_)); |
| } |
| gvr_buffer_viewport_list_get_item(cobj(), index, |
| viewport->cobj()); |
| } |
| |
| /// For more information, see gvr_buffer_viewport_list_get_size(). |
| size_t GetSize() const { |
| return gvr_buffer_viewport_list_get_size(cobj()); |
| } |
| |
| /// @name Wrapper manipulation |
| /// @{ |
| /// Creates a C++ wrapper for a C object and takes ownership. |
| BufferViewportList(gvr_buffer_viewport_list* viewport_list, |
| gvr_context* context) |
| : WrapperBase(viewport_list), context_(context) {} |
| /// @} |
| |
| private: |
| gvr_context* context_; |
| }; |
| |
| /// Convenience C++ wrapper for gvr_buffer_spec, an opaque pixel buffer |
| /// specification. Frees the underlying gvr_buffer_spec on destruction. |
| class BufferSpec |
| : public WrapperBase<gvr_buffer_spec, gvr_buffer_spec_destroy> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// Gets the buffer's size. The default value is the recommended render |
| /// target size. For more information, see gvr_buffer_spec_get_size(). |
| Sizei GetSize() const { |
| return gvr_buffer_spec_get_size(cobj()); |
| } |
| |
| /// Sets the buffer's size. For more information, see |
| /// gvr_buffer_spec_set_size(). |
| void SetSize(const Sizei& size) { |
| gvr_buffer_spec_set_size(cobj(), size); |
| } |
| |
| /// Sets the buffer's size to the passed width and height. For more |
| /// information, see gvr_buffer_spec_set_size(). |
| /// |
| /// @param width The width in pixels. Must be greater than 0. |
| /// @param height The height in pixels. Must be greater than 0. |
| void SetSize(int32_t width, int32_t height) { |
| gvr_sizei size{width, height}; |
| gvr_buffer_spec_set_size(cobj(), size); |
| } |
| |
| /// Gets the number of samples per pixel in the buffer. For more |
| /// information, see gvr_buffer_spec_get_samples(). |
| int32_t GetSamples() const { return gvr_buffer_spec_get_samples(cobj()); } |
| |
| /// Sets the number of samples per pixel. For more information, see |
| /// gvr_buffer_spec_set_samples(). |
| void SetSamples(int32_t num_samples) { |
| gvr_buffer_spec_set_samples(cobj(), num_samples); |
| } |
| |
| /// Sets the color format for this buffer. For more information, see |
| /// gvr_buffer_spec_set_color_format(). |
| void SetColorFormat(ColorFormat color_format) { |
| gvr_buffer_spec_set_color_format(cobj(), color_format); |
| } |
| |
| /// Sets the depth and stencil format for this buffer. For more |
| /// information, see gvr_buffer_spec_set_depth_stencil_format(). |
| void SetDepthStencilFormat(DepthStencilFormat depth_stencil_format) { |
| gvr_buffer_spec_set_depth_stencil_format(cobj(), depth_stencil_format); |
| } |
| |
| /// For more information, see gvr_buffer_spec_set_multiview_layers(). |
| void SetMultiviewLayers(int32_t num_layers) { |
| gvr_buffer_spec_set_multiview_layers(cobj(), num_layers); |
| } |
| }; |
| |
| /// Convenience C++ wrapper for gvr_frame, which represents a single frame |
| /// acquired for rendering from the swap chain. |
| class Frame : public WrapperBase<gvr_frame> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// For more information, see gvr_frame_get_buffer_size(). |
| Sizei GetBufferSize(int32_t index) const { |
| return gvr_frame_get_buffer_size(cobj(), index); |
| } |
| |
| /// For more information, see gvr_frame_bind_buffer(). |
| void BindBuffer(int32_t index) { |
| gvr_frame_bind_buffer(cobj(), index); |
| } |
| |
| /// For more information, see gvr_frame_unbind(). |
| void Unbind() { |
| gvr_frame_unbind(cobj()); |
| } |
| |
| /// For more information, see gvr_frame_get_framebuffer_object(). |
| int32_t GetFramebufferObject(int32_t index) const { |
| return gvr_frame_get_framebuffer_object(cobj(), index); |
| } |
| |
| /// For more information, see gvr_frame_get_hardware_buffer(). |
| void* GetHardwareBuffer(int32_t index) const { |
| return gvr_frame_get_hardware_buffer(cobj(), index); |
| } |
| |
| /// For more information, see gvr_frame_submit(). |
| void Submit(const BufferViewportList& viewport_list, |
| const Mat4f& head_space_from_start_space) { |
| gvr_frame_submit(&cobject_, viewport_list.cobj(), |
| head_space_from_start_space); |
| } |
| }; |
| |
| /// Convenience C++ wrapper for gvr_swap_chain, which represents a queue of |
| /// frames. The GvrApi object must outlive any SwapChain objects created from |
| /// it. |
| class SwapChain : public WrapperBase<gvr_swap_chain, gvr_swap_chain_destroy> { |
| public: |
| using WrapperBase::WrapperBase; |
| |
| /// For more information, see gvr_swap_chain_get_buffer_count(). |
| int32_t GetBufferCount() const { |
| return gvr_swap_chain_get_buffer_count(cobj()); |
| } |
| |
| /// For more information, see gvr_swap_chain_get_buffer_size(). |
| Sizei GetBufferSize(int32_t index) const { |
| return gvr_swap_chain_get_buffer_size(cobj(), index); |
| } |
| |
| /// For more information, see gvr_swap_chain_resize_buffer(). |
| void ResizeBuffer(int32_t index, Sizei size) { |
| gvr_swap_chain_resize_buffer(cobj(), index, size); |
| } |
| |
| /// For more information, see gvr_swap_chain_acquire_frame(). |
| /// Note that if Frame acquisition fails, the returned Frame may not be valid. |
| /// The caller should inspect the returned Frame's validity before using, |
| /// and reschedule frame acquisition upon failure. |
| Frame AcquireFrame() { |
| Frame result(gvr_swap_chain_acquire_frame(cobj())); |
| return result; |
| } |
| |
| private: |
| friend class GvrApi; |
| |
| SwapChain(gvr_context* context, const std::vector<BufferSpec>& specs) { |
| std::vector<const gvr_buffer_spec*> c_specs; |
| for (const auto& spec : specs) |
| c_specs.push_back(spec.cobj()); |
| cobject_ = gvr_swap_chain_create(context, c_specs.data(), |
| static_cast<int32_t>(c_specs.size())); |
| } |
| }; |
| |
| /// This is a convenience C++ wrapper for the Google VR C API. |
| /// |
| /// This wrapper strategy prevents ABI compatibility issues between compilers |
| /// by ensuring that the interface between client code and the implementation |
| /// code in libgvr.so is a pure C interface. The translation from C++ calls |
| /// to C calls provided by this wrapper runs entirely in the client's binary |
| /// and is compiled by the client's compiler. |
| /// |
| /// Methods in this class are only documented insofar as the C++ wrapping logic |
| /// is concerned; for information about the method itself, please refer to the |
| /// corresponding function in the C API. |
| /// |
| /// Example API usage: |
| /// |
| /// // Functionality supplied by the application in the example below has |
| /// // the "app-" prefix. |
| /// #ifdef __ANDROID__ |
| /// // On Android, the gvr_context should almost always be obtained from the |
| /// // Java GvrLayout object via |
| /// // GvrLayout.getGvrApi().getNativeGvrContext(). |
| /// std::unique_ptr<GvrApi> gvr = GvrApi::WrapNonOwned(gvr_context); |
| /// #else |
| /// std::unique_ptr<GvrApi> gvr = GvrApi::Create(); |
| /// #endif |
| /// |
| /// gvr->InitializeGl(); |
| /// |
| /// gvr::BufferViewportList viewport_list = |
| /// gvr->CreateEmptyBufferViewportList(); |
| /// gvr->GetRecommendedBufferViewports(&viewport_list); |
| /// gvr::BufferViewport left_eye_viewport = gvr->CreateBufferViewport(); |
| /// gvr::BufferViewport right_eye_viewport = gvr->CreateBufferViewport(); |
| /// viewport_list.Get(0, &left_eye_view); |
| /// viewport_list.Get(1, &right_eye_view); |
| /// |
| /// std::vector<gvr::BufferSpec> specs; |
| /// specs.push_back(gvr->CreateBufferSpec()); |
| /// specs[0].SetSamples(app_samples); |
| /// gvr::SwapChain swap_chain = gvr->CreateSwapChain(specs); |
| /// |
| /// while (client_app_should_render) { |
| /// // A client app should be ready for the render target size to change |
| /// // whenever a new QR code is scanned, or a new viewer is paired. |
| /// gvr::Sizei render_target_size = |
| /// gvr->GetRecommendedRenderTargetSize(); |
| /// swap_chain.ResizeBuffer(0, render_target_size); |
| /// gvr::Frame frame = swap_chain.AcquireFrame(); |
| /// while (!frame) { |
| /// std::this_thread::sleep_for(2ms); |
| /// frame = swap_chain.AcquireFrame(); |
| /// } |
| /// |
| /// // This function will depend on your render loop's implementation. |
| /// gvr::ClockTimePoint next_vsync = AppGetNextVsyncTime(); |
| /// |
| /// const gvr::Mat4f head_view = |
| /// gvr->GetHeadSpaceFromStartSpaceRotation(next_vsync); |
| /// const gvr::Mat4f left_eye_view = MatrixMultiply( |
| /// gvr->GetEyeFromHeadMatrix(kLeftEye), head_view); |
| /// const gvr::Mat4f right_eye_view = MatrixMultiply( |
| /// gvr->GetEyeFromHeadMatrix(kRightEye), head_view); |
| /// |
| /// frame.BindBuffer(0); |
| /// // App does its rendering to the current framebuffer here. |
| /// AppDoSomeRenderingForEye( |
| /// left_eye_viewport.GetSourceUv(), left_eye_view); |
| /// AppDoSomeRenderingForEye( |
| /// right_eye_viewport.GetSourceUv(), right_eye_view); |
| /// frame.Unbind(); |
| /// frame.Submit(viewport_list, head_view); |
| /// } |
| /// |
| class GvrApi { |
| public: |
| #ifdef __ANDROID__ |
| /// Instantiates and returns a GvrApi instance that owns a gvr_context. |
| /// |
| /// @param env The JNIEnv associated with the current thread. |
| /// @param app_context The Android application context. This must be the |
| /// application context, NOT an Activity context (Note: from any Android |
| /// Activity in your app, you can call getApplicationContext() to |
| /// retrieve the application context). |
| /// @param class_loader The class loader to use when loading Java classes. |
| /// This must be your app's main class loader (usually accessible through |
| /// activity.getClassLoader() on any of your Activities). |
| /// @return unique_ptr to the created GvrApi instance, nullptr on failure. |
| static std::unique_ptr<GvrApi> Create(JNIEnv* env, jobject app_context, |
| jobject class_loader) { |
| gvr_context* context = gvr_create(env, app_context, class_loader); |
| if (!context) { |
| return nullptr; |
| } |
| return std::unique_ptr<GvrApi>(new GvrApi(context, /*owned=*/true)); |
| } |
| #else |
| /// Instantiates and returns a GvrApi instance that owns a gvr_context. |
| /// |
| /// @return unique_ptr to the created GvrApi instance, nullptr on failure. |
| static std::unique_ptr<GvrApi> Create() { |
| gvr_context* context = gvr_create(); |
| if (!context) { |
| return nullptr; |
| } |
| return std::unique_ptr<GvrApi>(new GvrApi(context, /*owned=*/true)); |
| } |
| #endif // #ifdef __ANDROID__ |
| |
| ~GvrApi() { |
| if (context_ && owned_) { |
| gvr_destroy(&context_); |
| } |
| } |
| |
| /// @name Error handling |
| /// @{ |
| |
| /// For more information, see gvr_get_error(). |
| Error GetError() { return static_cast<Error>(gvr_get_error(context_)); } |
| |
| /// For more information, see gvr_clear_error(). |
| Error ClearError() { return static_cast<Error>(gvr_clear_error(context_)); } |
| |
| /// For more information, see gvr_get_error_string(). |
| static const char* GetErrorString(Error error_code) { |
| return gvr_get_error_string(error_code); |
| } |
| |
| /// For more information, see gvr_poll_event(). |
| bool PollEvent(Event* event_out) { |
| return gvr_poll_event(context_, event_out) == GVR_ERROR_NONE; |
| } |
| |
| /// For more information, see gvr_get_current_properties(). |
| Properties GetCurrentProperties() { |
| return Properties(gvr_get_current_properties(context_)); |
| } |
| |
| /// For more information, see gvr_get_user_prefs(). |
| UserPrefs GetUserPrefs() const { |
| return UserPrefs(gvr_get_user_prefs(context_)); |
| } |
| |
| /// @} |
| |
| /// @name Rendering |
| /// @{ |
| |
| /// For more information, see gvr_initialize_gl(). |
| void InitializeGl() { gvr_initialize_gl(context_); } |
| |
| /// For more information, see gvr_get_async_reprojection_enabled(). |
| bool GetAsyncReprojectionEnabled() const { |
| return gvr_get_async_reprojection_enabled(context_); |
| } |
| |
| /// Constructs a C++ wrapper for a gvr_buffer_viewport object. For more |
| /// information, see gvr_buffer_viewport_create(). |
| /// |
| /// @return A new BufferViewport instance with memory allocated for an |
| /// underlying gvr_buffer_viewport. |
| BufferViewport CreateBufferViewport() const { |
| return BufferViewport(gvr_buffer_viewport_create(context_)); |
| } |
| |
| /// Constructs a C++ wrapper for a gvr_buffer_viewport_list object. |
| /// For more information, see gvr_buffer_viewport_list_create(). |
| /// |
| /// @return A new, empty BufferViewportList instance. |
| /// Note: The validity of the returned object is closely tied to the |
| /// lifetime of the member gvr_context. The caller is responsible for |
| /// ensuring correct usage accordingly. |
| BufferViewportList CreateEmptyBufferViewportList() const { |
| return BufferViewportList(gvr_buffer_viewport_list_create(context_), |
| context_); |
| } |
| |
| /// For more information, see gvr_get_maximum_effective_render_target_size(). |
| Sizei GetMaximumEffectiveRenderTargetSize() const { |
| return gvr_get_maximum_effective_render_target_size(context_); |
| } |
| |
| /// For more information, see gvr_get_screen_target_size(). |
| Sizei GetScreenTargetSize() const { |
| return gvr_get_screen_target_size(context_); |
| } |
| |
| /// For more information, see gvr_set_surface_size(). |
| void SetSurfaceSize(Sizei surface_size_pixels) { |
| gvr_set_surface_size(context_, surface_size_pixels); |
| } |
| |
| /// For more information, see gvr_distort_to_screen(). |
| void DistortToScreen(int32_t texture_id, |
| const BufferViewportList& viewport_list, |
| const Mat4f& rendered_head_pose_in_start_space_matrix, |
| const ClockTimePoint& texture_presentation_time) { |
| gvr_distort_to_screen(context_, texture_id, viewport_list.cobj(), |
| rendered_head_pose_in_start_space_matrix, |
| texture_presentation_time); |
| } |
| |
| /// For more information, see gvr_is_feature_supported(). |
| bool IsFeatureSupported(int32_t feature) { |
| return gvr_is_feature_supported(context_, feature); |
| } |
| |
| /// For more information, see gvr_buffer_spec_create(). |
| BufferSpec CreateBufferSpec() { |
| return BufferSpec(gvr_buffer_spec_create(context_)); |
| } |
| |
| /// For more information, see gvr_swap_chain_create(). |
| SwapChain CreateSwapChain(const std::vector<BufferSpec>& specs) { |
| return SwapChain(context_, specs); |
| } |
| |
| /// For more information, see gvr_bind_default_framebuffer(). |
| void BindDefaultFramebuffer() { |
| gvr_bind_default_framebuffer(context_); |
| } |
| /// @} |
| |
| /// @name Head tracking |
| /// @{ |
| |
| /// For more information see gvr_get_head_space_from_start_space_rotation. |
| Mat4f GetHeadSpaceFromStartSpaceRotation( |
| const ClockTimePoint& time_point) const { |
| return gvr_get_head_space_from_start_space_rotation(context_, time_point); |
| } |
| |
| /// For more information see gvr_get_head_space_from_start_space_transform. |
| Mat4f GetHeadSpaceFromStartSpaceTransform( |
| const ClockTimePoint& time_point) const { |
| return gvr_get_head_space_from_start_space_transform(context_, time_point); |
| } |
| |
| /// For more information, see gvr_apply_neck_model(). |
| Mat4f ApplyNeckModel(const Mat4f& head_space_from_start_space_rotation, |
| float factor) const { |
| return gvr_apply_neck_model(context_, head_space_from_start_space_rotation, |
| factor); |
| } |
| |
| /// For more information, see gvr_pause_tracking(). |
| void PauseTracking() { gvr_pause_tracking(context_); } |
| |
| /// For more information, see gvr_resume_tracking(). |
| void ResumeTracking() { gvr_resume_tracking(context_); } |
| |
| /// For more information, see gvr_reset_tracking(). |
| void ResetTracking() { gvr_reset_tracking(context_); } |
| |
| // For more information, see gvr_recenter_tracking(). |
| void RecenterTracking() { gvr_recenter_tracking(context_); } |
| |
| /// For more information, see gvr_get_time_point_now(). |
| static ClockTimePoint GetTimePointNow() { return gvr_get_time_point_now(); } |
| /// @} |
| |
| /// @name Viewer parameters |
| /// @{ |
| |
| /// For more information, see gvr_set_default_viewer_profile(). |
| bool SetDefaultViewerProfile(const char* viewer_profile_uri) { |
| return gvr_set_default_viewer_profile(context_, viewer_profile_uri); |
| } |
| |
| /// For more information, see gvr_refresh_viewer_profile(). |
| void RefreshViewerProfile() { gvr_refresh_viewer_profile(context_); } |
| |
| /// For more information, see gvr_get_viewer_vendor(). |
| const char* GetViewerVendor() const { |
| return gvr_get_viewer_vendor(context_); |
| } |
| |
| /// For more information, see gvr_get_viewer_model(). |
| const char* GetViewerModel() const { return gvr_get_viewer_model(context_); } |
| |
| /// For more information, see gvr_get_viewer_type(). |
| ViewerType GetViewerType() const { |
| return static_cast<ViewerType>(gvr_get_viewer_type(context_)); |
| } |
| |
| /// For more information, see gvr_get_eye_from_head_matrix(). |
| Mat4f GetEyeFromHeadMatrix(Eye eye) const { |
| return gvr_get_eye_from_head_matrix(context_, eye); |
| } |
| |
| /// For more information, see gvr_get_window_bounds(). |
| Recti GetWindowBounds() const { return gvr_get_window_bounds(context_); } |
| |
| /// For more information, see gvr_compute_distorted_point(). |
| std::array<Vec2f, 3> ComputeDistortedPoint(Eye eye, const Vec2f& uv_in) { |
| std::array<Vec2f, 3> uv_out = {{{}}}; |
| gvr_compute_distorted_point(context_, eye, uv_in, uv_out.data()); |
| return uv_out; |
| } |
| /// @} |
| |
| /// @name Wrapper manipulation |
| /// @{ |
| /// Creates a C++ wrapper for a C object and optionally takes ownership. |
| /// |
| /// @param context C object to wrap. |
| /// @param owned Whether the wrapper will own the underlying C object. |
| explicit GvrApi(gvr_context* context, bool owned = true) |
| : context_(context), owned_(owned) {} |
| |
| /// Returns the wrapped C object. Does not affect ownership. |
| gvr_context* cobj() { return context_; } |
| const gvr_context* cobj() const { return context_; } |
| |
| /// @deprecated Use cobj() instead. |
| gvr_context* GetContext() { return context_; } |
| /// @deprecated Use cobj() instead. |
| const gvr_context* GetContext() const { return context_; } |
| |
| /// Returns the wrapped C object and transfers its ownership to the caller. |
| /// The wrapper becomes invalid and should not be used. |
| gvr_context* release() { |
| auto result = context_; |
| context_ = nullptr; |
| return result; |
| } |
| |
| /// Instantiates a GvrApi instance that wraps a *non-owned* gvr_context. |
| /// |
| /// Ownership of the provided `context` remains with the caller, and they |
| /// are responsible for ensuring proper disposal of the context. |
| /// |
| /// @param context Pointer to a non-null, non-owned gvr_context instance. |
| /// @return unique_ptr to the created GvrApi instance. Never null. |
| static std::unique_ptr<GvrApi> WrapNonOwned(gvr_context* context) { |
| return std::unique_ptr<GvrApi>(new GvrApi(context, /*owned=*/false)); |
| } |
| /// @} |
| |
| // Disallow copy and assign. |
| GvrApi(const GvrApi&) = delete; |
| void operator=(const GvrApi&) = delete; |
| |
| private: |
| gvr_context* context_; |
| |
| // Whether context_ is owned by the GvrApi instance. If owned, the context |
| // will be released upon destruction. |
| const bool owned_; |
| }; |
| |
| } // namespace gvr |
| #endif // #if defined(__cplusplus) && !defined(GVR_NO_CPP_WRAPPER) |
| |
| #endif // VR_GVR_CAPI_INCLUDE_GVR_H_ |