mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Merge pull request #14803 from highfidelity/feature/quest
Case 20624: Final merge of Quest Interface application into master
This commit is contained in:
commit
4dbae787cb
51 changed files with 864 additions and 212 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,6 +24,7 @@ android/**/bin
|
||||||
android/**/src/main/res/values/libs.xml
|
android/**/src/main/res/values/libs.xml
|
||||||
android/**/src/main/assets
|
android/**/src/main/assets
|
||||||
android/**/gradle*
|
android/**/gradle*
|
||||||
|
*.class
|
||||||
|
|
||||||
# VSCode
|
# VSCode
|
||||||
# List taken from Github Global Ignores master@435c4d92
|
# List taken from Github Global Ignores master@435c4d92
|
||||||
|
|
65
BUILD_QUEST.md
Normal file
65
BUILD_QUEST.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
Please read the [general build guide](BUILD.md) for information on building other platform. Only Quest specific instructions are found in this file.
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
Building is currently supported on OSX, Windows and Linux platforms, but developers intending to do work on the library dependencies are strongly urged to use 64 bit Linux as a build platform
|
||||||
|
|
||||||
|
You will need the following tools to build Android targets.
|
||||||
|
|
||||||
|
* [Android Studio](https://developer.android.com/studio/index.html)
|
||||||
|
|
||||||
|
### Android Studio
|
||||||
|
|
||||||
|
Download the Android Studio installer and run it. Once installed, at the welcome screen, click configure in the lower right corner and select SDK manager
|
||||||
|
|
||||||
|
From the SDK Platforms tab, select API levels 24 and 26.
|
||||||
|
|
||||||
|
From the SDK Tools tab select the following
|
||||||
|
|
||||||
|
* Android SDK Build-Tools
|
||||||
|
* GPU Debugging Tools
|
||||||
|
* CMake (even if you have a separate CMake installation)
|
||||||
|
* LLDB
|
||||||
|
* Android SDK Platform-Tools
|
||||||
|
* Android SDK Tools
|
||||||
|
* NDK (even if you have the NDK installed separately)
|
||||||
|
|
||||||
|
Make sure the NDK installed version is 18 (or higher)
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
|
||||||
|
Setting up the environment for android builds requires some additional steps
|
||||||
|
|
||||||
|
#### Set up machine specific Gradle properties
|
||||||
|
|
||||||
|
Create a `gradle.properties` file in $HOME/.gradle. Edit the file to contain the following
|
||||||
|
|
||||||
|
HIFI_ANDROID_PRECOMPILED=<your_home_directory>/Android/hifi_externals
|
||||||
|
HIFI_ANDROID_KEYSTORE=<key_store_directory>/<keystore_name>.jks
|
||||||
|
HIFI_ANDROID_KEYSTORE_PASSWORD=<password>
|
||||||
|
HIFI_ANDROID_KEY_ALIAS=<key_alias>
|
||||||
|
HIFI_ANDROID_KEY_PASSWORD=<key_password>
|
||||||
|
|
||||||
|
Note, do not use `$HOME` for the path. It must be a fully qualified path name.
|
||||||
|
|
||||||
|
### Setup the repository
|
||||||
|
|
||||||
|
Clone the repository
|
||||||
|
|
||||||
|
`git clone https://github.com/highfidelity/hifi.git`
|
||||||
|
|
||||||
|
Enter the repository `android` directory
|
||||||
|
|
||||||
|
`cd hifi/android`
|
||||||
|
|
||||||
|
# Building & Running
|
||||||
|
|
||||||
|
* Open Android Studio
|
||||||
|
* Choose _Open Existing Android Studio Project_
|
||||||
|
* Navigate to the `hifi` repository and choose the `android` folder and select _OK_
|
||||||
|
* Open Gradle.settings and comment out any projects not necessary
|
||||||
|
* From _File_ menu select _Sync with File System_ to resync Gradle settings
|
||||||
|
* From the _Build_ menu select _Make Project_
|
||||||
|
* From
|
||||||
|
* Once the build completes, from the _Run_ menu select _Run App_
|
||||||
|
|
|
@ -100,6 +100,13 @@ if (ANDROID)
|
||||||
add_definitions(-DCUSTOM_DISPLAY_PLUGINS)
|
add_definitions(-DCUSTOM_DISPLAY_PLUGINS)
|
||||||
set(PLATFORM_PLUGIN_LIBRARIES oculusMobile oculusMobilePlugin)
|
set(PLATFORM_PLUGIN_LIBRARIES oculusMobile oculusMobilePlugin)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Allow client code to use preprocessor macros to distinguish between quest and non-quest builds
|
||||||
|
if (${HIFI_ANDROID_APP} STREQUAL "questInterface")
|
||||||
|
add_definitions(-DANDROID_APP_QUEST_INTERFACE)
|
||||||
|
elseif(${HIFI_ANDROID_APP} STREQUAL "interface")
|
||||||
|
add_definitions(-DANDROID_APP_INTERFACE)
|
||||||
|
endif()
|
||||||
else ()
|
else ()
|
||||||
set(PLATFORM_QT_COMPONENTS WebEngine Xml)
|
set(PLATFORM_QT_COMPONENTS WebEngine Xml)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -81,6 +81,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
private boolean nativeEnterBackgroundCallEnqueued = false;
|
private boolean nativeEnterBackgroundCallEnqueued = false;
|
||||||
private SlidingDrawer mWebSlidingDrawer;
|
private SlidingDrawer mWebSlidingDrawer;
|
||||||
private boolean mStartInDomain;
|
private boolean mStartInDomain;
|
||||||
|
private boolean isLoading;
|
||||||
// private GvrApi gvrApi;
|
// private GvrApi gvrApi;
|
||||||
// Opaque native pointer to the Application C++ object.
|
// Opaque native pointer to the Application C++ object.
|
||||||
// This object is owned by the InterfaceActivity instance and passed to the native methods.
|
// This object is owned by the InterfaceActivity instance and passed to the native methods.
|
||||||
|
@ -94,7 +95,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.isLoading = true;
|
isLoading = true;
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
if (intent.hasExtra(DOMAIN_URL) && !TextUtils.isEmpty(intent.getStringExtra(DOMAIN_URL))) {
|
if (intent.hasExtra(DOMAIN_URL) && !TextUtils.isEmpty(intent.getStringExtra(DOMAIN_URL))) {
|
||||||
intent.putExtra("applicationArguments", "--url " + intent.getStringExtra(DOMAIN_URL));
|
intent.putExtra("applicationArguments", "--url " + intent.getStringExtra(DOMAIN_URL));
|
||||||
|
@ -145,7 +146,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
if (super.isLoading) {
|
if (isLoading) {
|
||||||
nativeEnterBackgroundCallEnqueued = true;
|
nativeEnterBackgroundCallEnqueued = true;
|
||||||
} else {
|
} else {
|
||||||
nativeEnterBackground();
|
nativeEnterBackground();
|
||||||
|
@ -172,7 +173,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
super.onResume();
|
super.onResume();
|
||||||
nativeEnterForeground();
|
nativeEnterForeground();
|
||||||
surfacesWorkaround();
|
surfacesWorkaround();
|
||||||
keepInterfaceRunning = false;
|
|
||||||
registerReceiver(headsetStateReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
|
registerReceiver(headsetStateReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
|
||||||
//gvrApi.resumeTracking();
|
//gvrApi.resumeTracking();
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAppLoadedComplete() {
|
public void onAppLoadedComplete() {
|
||||||
super.isLoading = false;
|
isLoading = false;
|
||||||
if (nativeEnterBackgroundCallEnqueued) {
|
if (nativeEnterBackgroundCallEnqueued) {
|
||||||
nativeEnterBackground();
|
nativeEnterBackground();
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,6 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExpand() {
|
public void onExpand() {
|
||||||
keepInterfaceRunning = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
set(TARGET_NAME questFramePlayer)
|
set(TARGET_NAME questFramePlayer)
|
||||||
setup_hifi_library(AndroidExtras)
|
setup_hifi_library(AndroidExtras)
|
||||||
link_hifi_libraries(shared ktx shaders gpu gl oculusMobile ${PLATFORM_GL_BACKEND})
|
link_hifi_libraries(shared ktx shaders gpu gl oculusMobile ${PLATFORM_GL_BACKEND})
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${HIFI_ANDROID_PRECOMPILED}/ovr/VrApi/Include)
|
|
||||||
target_link_libraries(${TARGET_NAME} android log m)
|
target_link_libraries(${TARGET_NAME} android log m)
|
||||||
target_opengl()
|
target_opengl()
|
||||||
target_oculus_mobile()
|
target_oculus_mobile()
|
||||||
|
|
|
@ -19,24 +19,6 @@
|
||||||
android:name="org.qtproject.qt5.android.bindings.QtApplication"
|
android:name="org.qtproject.qt5.android.bindings.QtApplication"
|
||||||
tools:ignore="GoogleAppIndexingWarning,MissingApplicationIcon">
|
tools:ignore="GoogleAppIndexingWarning,MissingApplicationIcon">
|
||||||
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
||||||
<activity
|
|
||||||
android:name=".QuestQtActivity"
|
|
||||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
|
||||||
android:launchMode="singleTask"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:screenOrientation="landscape"
|
|
||||||
android:excludeFromRecents="false"
|
|
||||||
android:alwaysRetainTaskState="true"
|
|
||||||
android:configChanges="screenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode"
|
|
||||||
>
|
|
||||||
<!-- JNI nonsense -->
|
|
||||||
<meta-data android:name="android.app.lib_name" android:value="questFramePlayer"/>
|
|
||||||
<!-- Qt nonsense -->
|
|
||||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
|
||||||
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
|
||||||
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
|
||||||
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so:lib/libQt5QuickParticles.so"/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
||||||
|
@ -50,6 +32,13 @@
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<!-- JNI nonsense -->
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="questFramePlayer"/>
|
||||||
|
<!-- Qt nonsense -->
|
||||||
|
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||||
|
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so:lib/libQt5QuickParticles.so"/>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
30
android/apps/questFramePlayer/src/main/cpp/AndroidHelper.cpp
Normal file
30
android/apps/questFramePlayer/src/main/cpp/AndroidHelper.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/02/15
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "AndroidHelper.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtGui/QGuiApplication>
|
||||||
|
|
||||||
|
AndroidHelper::AndroidHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidHelper::~AndroidHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::notifyLoadComplete() {
|
||||||
|
emit qtAppLoadComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::notifyEnterForeground() {
|
||||||
|
emit enterForeground();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidHelper::notifyEnterBackground() {
|
||||||
|
emit enterBackground();
|
||||||
|
}
|
||||||
|
|
43
android/apps/questFramePlayer/src/main/cpp/AndroidHelper.h
Normal file
43
android/apps/questFramePlayer/src/main/cpp/AndroidHelper.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/02/15
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_Android_Helper_h
|
||||||
|
#define hifi_Android_Helper_h
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QEventLoop>
|
||||||
|
|
||||||
|
class AndroidHelper : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AndroidHelper(AndroidHelper const&) = delete;
|
||||||
|
void operator=(AndroidHelper const&) = delete;
|
||||||
|
|
||||||
|
static AndroidHelper& instance() {
|
||||||
|
static AndroidHelper instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyLoadComplete();
|
||||||
|
void notifyEnterForeground();
|
||||||
|
void notifyEnterBackground();
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void qtAppLoadComplete();
|
||||||
|
void enterForeground();
|
||||||
|
void enterBackground();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AndroidHelper();
|
||||||
|
~AndroidHelper();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -11,15 +11,11 @@
|
||||||
#include <QtWidgets/QFileDialog>
|
#include <QtWidgets/QFileDialog>
|
||||||
|
|
||||||
PlayerWindow::PlayerWindow() {
|
PlayerWindow::PlayerWindow() {
|
||||||
installEventFilter(this);
|
setFlags(Qt::Window);
|
||||||
setFlags(Qt::MSWindowsOwnDC | Qt::Window | Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowTitleHint);
|
|
||||||
setSurfaceType(QSurface::OpenGLSurface);
|
setSurfaceType(QSurface::OpenGLSurface);
|
||||||
create();
|
create();
|
||||||
showFullScreen();
|
showFullScreen();
|
||||||
// Ensure the window is visible and the GL context is valid
|
// Ensure the window is visible and the GL context is valid
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
_renderThread.initialize(this);
|
_renderThread.initialize();
|
||||||
}
|
|
||||||
|
|
||||||
PlayerWindow::~PlayerWindow() {
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
#include <QtCore/QSettings>
|
|
||||||
|
|
||||||
#include <gpu/Forward.h>
|
|
||||||
#include "RenderThread.h"
|
#include "RenderThread.h"
|
||||||
|
|
||||||
// Create a simple OpenGL window that renders text in various ways
|
|
||||||
class PlayerWindow : public QWindow {
|
class PlayerWindow : public QWindow {
|
||||||
public:
|
public:
|
||||||
PlayerWindow();
|
PlayerWindow();
|
||||||
virtual ~PlayerWindow();
|
virtual ~PlayerWindow() {}
|
||||||
|
|
||||||
protected:
|
|
||||||
//bool eventFilter(QObject* obj, QEvent* event) override;
|
|
||||||
//void keyPressEvent(QKeyEvent* event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings _settings;
|
|
||||||
RenderThread _renderThread;
|
RenderThread _renderThread;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
#include <QtGui/QImageReader>
|
#include <QtGui/QImageReader>
|
||||||
|
#include <QtAndroidExtras/QAndroidJniObject>
|
||||||
|
|
||||||
#include <gl/QOpenGLContextWrapper.h>
|
#include <gl/QOpenGLContextWrapper.h>
|
||||||
#include <gpu/FrameIO.h>
|
#include <gpu/FrameIO.h>
|
||||||
|
@ -29,9 +30,7 @@
|
||||||
#include <VrApi.h>
|
#include <VrApi.h>
|
||||||
#include <VrApi_Input.h>
|
#include <VrApi_Input.h>
|
||||||
|
|
||||||
static JNIEnv* _env { nullptr };
|
#include "AndroidHelper.h"
|
||||||
static JavaVM* _vm { nullptr };
|
|
||||||
static jobject _activity { nullptr };
|
|
||||||
|
|
||||||
struct HandController{
|
struct HandController{
|
||||||
ovrInputTrackedRemoteCapabilities caps {};
|
ovrInputTrackedRemoteCapabilities caps {};
|
||||||
|
@ -48,21 +47,43 @@ struct HandController{
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<HandController> devices;
|
std::vector<HandController> devices;
|
||||||
|
QAndroidJniObject __interfaceActivity;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *, void *) {
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void *) {
|
||||||
__android_log_write(ANDROID_LOG_WARN, "QQQ", __FUNCTION__);
|
__android_log_write(ANDROID_LOG_WARN, "QQQ", __FUNCTION__);
|
||||||
return JNI_VERSION_1_6;
|
return JNI_VERSION_1_6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnCreate(JNIEnv *env, jobject obj) {
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "QQQ", __FUNCTION__);
|
||||||
|
__interfaceActivity = QAndroidJniObject(obj);
|
||||||
|
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, []() {
|
||||||
|
__interfaceActivity.callMethod<void>("onAppLoadedComplete", "()V");
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, nullptr, nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_io_highfidelity_frameplayer_QuestQtActivity_nativeOnCreate(JNIEnv* env, jobject obj) {
|
JNIEXPORT void
|
||||||
env->GetJavaVM(&_vm);
|
Java_io_highfidelity_oculus_OculusMobileActivity_questOnAppAfterLoad(JNIEnv *env, jobject obj) {
|
||||||
_activity = env->NewGlobalRef(obj);
|
AndroidHelper::instance().moveToThread(qApp->thread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnPause(JNIEnv *env, jobject obj) {
|
||||||
|
AndroidHelper::instance().notifyEnterBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnResume(JNIEnv *env, jobject obj) {
|
||||||
|
AndroidHelper::instance().notifyEnterForeground();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char* FRAME_FILE = "assets:/frames/20190121_1220.json";
|
static const char* FRAME_FILE = "assets:/frames/20190121_1220.json";
|
||||||
|
|
||||||
static void textureLoader(const std::string& filename, const gpu::TexturePointer& texture, uint16_t layer) {
|
static void textureLoader(const std::string& filename, const gpu::TexturePointer& texture, uint16_t layer) {
|
||||||
|
@ -84,11 +105,10 @@ void RenderThread::move(const glm::vec3& v) {
|
||||||
_correction = glm::inverse(glm::translate(mat4(), v)) * _correction;
|
_correction = glm::inverse(glm::translate(mat4(), v)) * _correction;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderThread::initialize(QWindow* window) {
|
void RenderThread::initialize() {
|
||||||
std::unique_lock<std::mutex> lock(_frameLock);
|
std::unique_lock<std::mutex> lock(_frameLock);
|
||||||
setObjectName("RenderThread");
|
setObjectName("RenderThread");
|
||||||
Parent::initialize();
|
Parent::initialize();
|
||||||
_window = window;
|
|
||||||
_thread->setObjectName("RenderThread");
|
_thread->setObjectName("RenderThread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,14 +116,7 @@ void RenderThread::setup() {
|
||||||
// Wait until the context has been moved to this thread
|
// Wait until the context has been moved to this thread
|
||||||
{ std::unique_lock<std::mutex> lock(_frameLock); }
|
{ std::unique_lock<std::mutex> lock(_frameLock); }
|
||||||
|
|
||||||
|
|
||||||
ovr::VrHandler::initVr();
|
ovr::VrHandler::initVr();
|
||||||
__android_log_write(ANDROID_LOG_WARN, "QQQ", "Launching oculus activity");
|
|
||||||
_vm->AttachCurrentThread(&_env, nullptr);
|
|
||||||
jclass cls = _env->GetObjectClass(_activity);
|
|
||||||
jmethodID mid = _env->GetMethodID(cls, "launchOculusActivity", "()V");
|
|
||||||
_env->CallVoidMethod(_activity, mid);
|
|
||||||
__android_log_write(ANDROID_LOG_WARN, "QQQ", "Launching oculus activity done");
|
|
||||||
ovr::VrHandler::setHandler(this);
|
ovr::VrHandler::setHandler(this);
|
||||||
|
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
|
@ -169,7 +182,6 @@ void RenderThread::handleInput() {
|
||||||
const auto &remote = controller.state;
|
const auto &remote = controller.state;
|
||||||
if (remote.Joystick.x != 0.0f || remote.Joystick.y != 0.0f) {
|
if (remote.Joystick.x != 0.0f || remote.Joystick.y != 0.0f) {
|
||||||
glm::vec3 translation;
|
glm::vec3 translation;
|
||||||
float rotation = 0.0f;
|
|
||||||
if (caps.ControllerCapabilities & ovrControllerCaps_LeftHand) {
|
if (caps.ControllerCapabilities & ovrControllerCaps_LeftHand) {
|
||||||
translation = glm::vec3{0.0f, -remote.Joystick.y, 0.0f};
|
translation = glm::vec3{0.0f, -remote.Joystick.y, 0.0f};
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,11 +20,9 @@
|
||||||
class RenderThread : public GenericThread, ovr::VrHandler {
|
class RenderThread : public GenericThread, ovr::VrHandler {
|
||||||
using Parent = GenericThread;
|
using Parent = GenericThread;
|
||||||
public:
|
public:
|
||||||
QWindow* _window{ nullptr };
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
gpu::ContextPointer _gpuContext; // initialized during window creation
|
gpu::ContextPointer _gpuContext; // initialized during window creation
|
||||||
std::shared_ptr<gpu::Backend> _backend;
|
std::shared_ptr<gpu::Backend> _backend;
|
||||||
std::atomic<size_t> _presentCount{ 0 };
|
|
||||||
std::mutex _frameLock;
|
std::mutex _frameLock;
|
||||||
std::queue<gpu::FramePointer> _pendingFrames;
|
std::queue<gpu::FramePointer> _pendingFrames;
|
||||||
gpu::FramePointer _activeFrame;
|
gpu::FramePointer _activeFrame;
|
||||||
|
@ -39,6 +37,6 @@ public:
|
||||||
void handleInput();
|
void handleInput();
|
||||||
|
|
||||||
void submitFrame(const gpu::FramePointer& frame);
|
void submitFrame(const gpu::FramePointer& frame);
|
||||||
void initialize(QWindow* window);
|
void initialize();
|
||||||
void renderFrame();
|
void renderFrame();
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,30 +11,33 @@
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtAndroidExtras/QAndroidJniObject>
|
||||||
|
|
||||||
#include <Trace.h>
|
#include <Trace.h>
|
||||||
|
|
||||||
#include "PlayerWindow.h"
|
#include "PlayerWindow.h"
|
||||||
|
#include "AndroidHelper.h"
|
||||||
|
|
||||||
|
|
||||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||||
if (!message.isEmpty()) {
|
if (!message.isEmpty()) {
|
||||||
const char * local=message.toStdString().c_str();
|
const char* local = message.toStdString().c_str();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QtDebugMsg:
|
case QtDebugMsg:
|
||||||
__android_log_write(ANDROID_LOG_DEBUG,"Interface",local);
|
__android_log_write(ANDROID_LOG_DEBUG, "Interface", local);
|
||||||
break;
|
break;
|
||||||
case QtInfoMsg:
|
case QtInfoMsg:
|
||||||
__android_log_write(ANDROID_LOG_INFO,"Interface",local);
|
__android_log_write(ANDROID_LOG_INFO, "Interface", local);
|
||||||
break;
|
break;
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
__android_log_write(ANDROID_LOG_WARN,"Interface",local);
|
__android_log_write(ANDROID_LOG_WARN, "Interface", local);
|
||||||
break;
|
break;
|
||||||
case QtCriticalMsg:
|
case QtCriticalMsg:
|
||||||
__android_log_write(ANDROID_LOG_ERROR,"Interface",local);
|
__android_log_write(ANDROID_LOG_ERROR, "Interface", local);
|
||||||
break;
|
break;
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
default:
|
default:
|
||||||
__android_log_write(ANDROID_LOG_FATAL,"Interface",local);
|
__android_log_write(ANDROID_LOG_FATAL, "Interface", local);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,11 +49,13 @@ int main(int argc, char** argv) {
|
||||||
auto oldMessageHandler = qInstallMessageHandler(messageHandler);
|
auto oldMessageHandler = qInstallMessageHandler(messageHandler);
|
||||||
DependencyManager::set<tracing::Tracer>();
|
DependencyManager::set<tracing::Tracer>();
|
||||||
PlayerWindow window;
|
PlayerWindow window;
|
||||||
__android_log_write(ANDROID_LOG_FATAL,"QQQ","Exec");
|
QTimer::singleShot(10, []{
|
||||||
|
__android_log_write(ANDROID_LOG_WARN, "QQQ", "notifyLoadComplete");
|
||||||
|
AndroidHelper::instance().notifyLoadComplete();
|
||||||
|
});
|
||||||
|
__android_log_write(ANDROID_LOG_WARN, "QQQ", "Exec");
|
||||||
app.exec();
|
app.exec();
|
||||||
__android_log_write(ANDROID_LOG_FATAL,"QQQ","Exec done");
|
__android_log_write(ANDROID_LOG_WARN, "QQQ", "Exec done");
|
||||||
qInstallMessageHandler(oldMessageHandler);
|
qInstallMessageHandler(oldMessageHandler);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2018/11/20
|
|
||||||
// Copyright 2013-2018 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
package io.highfidelity.frameplayer;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.qtproject.qt5.android.bindings.QtActivity;
|
|
||||||
|
|
||||||
import io.highfidelity.oculus.OculusMobileActivity;
|
|
||||||
|
|
||||||
|
|
||||||
public class QuestQtActivity extends QtActivity {
|
|
||||||
private native void nativeOnCreate();
|
|
||||||
private boolean launchedQuestMode = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
Log.w("QQQ_Qt", "QuestQtActivity::onCreate");
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
nativeOnCreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
Log.w("QQQ_Qt", "QuestQtActivity::onDestroy");
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launchOculusActivity() {
|
|
||||||
Log.w("QQQ_Qt", "QuestQtActivity::launchOculusActivity");
|
|
||||||
runOnUiThread(()->{
|
|
||||||
keepInterfaceRunning = true;
|
|
||||||
launchedQuestMode = true;
|
|
||||||
moveTaskToBack(true);
|
|
||||||
startActivity(new Intent(this, QuestRenderActivity.class));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if (launchedQuestMode) {
|
|
||||||
moveTaskToBack(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,6 @@
|
||||||
package io.highfidelity.frameplayer;
|
package io.highfidelity.frameplayer;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import io.highfidelity.oculus.OculusMobileActivity;
|
import io.highfidelity.oculus.OculusMobileActivity;
|
||||||
|
|
||||||
public class QuestRenderActivity extends OculusMobileActivity {
|
public class QuestRenderActivity extends OculusMobileActivity {
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedState) {
|
|
||||||
super.onCreate(savedState);
|
|
||||||
startActivity(new Intent(this, QuestQtActivity.class));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
16
android/apps/questInterface/CMakeLists.txt
Normal file
16
android/apps/questInterface/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
set(TARGET_NAME questInterface)
|
||||||
|
setup_hifi_library()
|
||||||
|
link_hifi_libraries(
|
||||||
|
shared task networking qml
|
||||||
|
image fbx hfm render-utils physics entities octree
|
||||||
|
oculusMobile oculusMobilePlugin
|
||||||
|
gl gpu ${PLATFORM_GL_BACKEND}
|
||||||
|
)
|
||||||
|
target_opengl()
|
||||||
|
target_bullet()
|
||||||
|
target_oculus_mobile()
|
||||||
|
|
||||||
|
add_subdirectory("${CMAKE_SOURCE_DIR}/interface" "libraries/interface")
|
||||||
|
include_directories("${CMAKE_SOURCE_DIR}/interface/src")
|
||||||
|
add_subdirectory("${CMAKE_SOURCE_DIR}/plugins/hifiCodec" "libraries/hifiCodecPlugin")
|
||||||
|
target_link_libraries(questInterface android log m interface)
|
149
android/apps/questInterface/build.gradle
Normal file
149
android/apps/questInterface/build.gradle
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
task renameHifiACTaskDebug() {
|
||||||
|
doLast {
|
||||||
|
def sourceFile = new File("${appDir}/build/intermediates/cmake/debug/obj/arm64-v8a/","libhifiCodec.so")
|
||||||
|
def destinationFile = new File("${appDir}/src/main/jniLibs/arm64-v8a", "libplugins_libhifiCodec.so")
|
||||||
|
copy { from sourceFile; into destinationFile.parent; rename(sourceFile.name, destinationFile.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task renameHifiACTaskRelease(type: Copy) {
|
||||||
|
doLast {
|
||||||
|
def sourceFile = new File("${appDir}/build/intermediates/cmake/release/obj/arm64-v8a/","libhifiCodec.so")
|
||||||
|
def destinationFile = new File("${appDir}/src/main/jniLibs/arm64-v8a", "libplugins_libhifiCodec.so")
|
||||||
|
copy { from sourceFile; into destinationFile.parent; rename(sourceFile.name, destinationFile.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 28
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "io.highfidelity.questInterface"
|
||||||
|
minSdkVersion 24
|
||||||
|
targetSdkVersion 28
|
||||||
|
versionCode 1
|
||||||
|
versionName appVersionName
|
||||||
|
ndk { abiFilters 'arm64-v8a' }
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
arguments '-DHIFI_ANDROID=1',
|
||||||
|
'-DHIFI_ANDROID_APP=questInterface',
|
||||||
|
'-DANDROID_TOOLCHAIN=clang',
|
||||||
|
'-DANDROID_STL=c++_shared',
|
||||||
|
'-DCMAKE_VERBOSE_MAKEFILE=ON',
|
||||||
|
'-DRELEASE_NUMBER=' + RELEASE_NUMBER,
|
||||||
|
'-DRELEASE_TYPE=' + RELEASE_TYPE,
|
||||||
|
'-DSTABLE_BUILD=' + STABLE_BUILD,
|
||||||
|
'-DDISABLE_QML=OFF',
|
||||||
|
'-DDISABLE_KTX_CACHE=OFF',
|
||||||
|
'-DUSE_BREAKPAD=OFF'
|
||||||
|
targets = ['questInterface']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null
|
||||||
|
storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : ''
|
||||||
|
keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : ''
|
||||||
|
keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : ''
|
||||||
|
v2SigningEnabled false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
|
||||||
|
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
|
||||||
|
}
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\""
|
||||||
|
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_CLIENT_SECRET", "\"" + (System.getenv("OAUTH_CLIENT_SECRET") ? System.getenv("OAUTH_CLIENT_SECRET") : '') + "\""
|
||||||
|
buildConfigField "String", "OAUTH_REDIRECT_URI", "\"" + (System.getenv("OAUTH_REDIRECT_URI") ? System.getenv("OAUTH_REDIRECT_URI") : '') + "\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path '../../../CMakeLists.txt'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
// Our asset contents depend on items produced in the CMake build
|
||||||
|
// so our merge has to depend on the external native build
|
||||||
|
variant.externalNativeBuildTasks.each { task ->
|
||||||
|
variant.mergeResources.dependsOn(task)
|
||||||
|
if (Os.isFamily(Os.FAMILY_UNIX)) {
|
||||||
|
// FIXME
|
||||||
|
def uploadDumpSymsTask = rootProject.getTasksByName("uploadBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
||||||
|
def runDumpSymsTask = rootProject.getTasksByName("runBreakpadDumpSyms${variant.name.capitalize()}", false).first()
|
||||||
|
def renameHifiACTask = rootProject.getTasksByName("renameHifiACTask${variant.name.capitalize()}", false).first()
|
||||||
|
runDumpSymsTask.dependsOn(task)
|
||||||
|
variant.assemble.dependsOn(uploadDumpSymsTask)
|
||||||
|
variant.mergeResources.dependsOn(renameHifiACTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant.mergeAssets.doLast {
|
||||||
|
def assetList = new LinkedList<String>()
|
||||||
|
def youngestLastModified = 0
|
||||||
|
|
||||||
|
// Copy the compiled resources generated by the external native build
|
||||||
|
copy {
|
||||||
|
from new File(projectDir, "../../../interface/compiledResources")
|
||||||
|
into outputDir
|
||||||
|
duplicatesStrategy DuplicatesStrategy.INCLUDE
|
||||||
|
eachFile { details ->
|
||||||
|
youngestLastModified = Math.max(youngestLastModified, details.lastModified)
|
||||||
|
assetList.add(details.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the scripts directory
|
||||||
|
copy {
|
||||||
|
from new File(projectDir, "../../../scripts")
|
||||||
|
into new File(outputDir, "scripts")
|
||||||
|
duplicatesStrategy DuplicatesStrategy.INCLUDE
|
||||||
|
eachFile { details->
|
||||||
|
youngestLastModified = Math.max(youngestLastModified, details.lastModified)
|
||||||
|
assetList.add("scripts/" + details.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a list of files to be unpacked to the cache folder
|
||||||
|
new File(outputDir, 'cache_assets.txt').withWriter { out ->
|
||||||
|
out.println(Long.toString(youngestLastModified))
|
||||||
|
assetList.each { file -> out.println(file) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant.outputs.all {
|
||||||
|
if (RELEASE_NUMBER != '0') {
|
||||||
|
outputFileName = "app_" + RELEASE_NUMBER + "_" + RELEASE_TYPE + ".apk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(include: ['*.jar'], dir: '../../libraries/qt/libs')
|
||||||
|
implementation project(':oculus')
|
||||||
|
implementation project(':qt')
|
||||||
|
}
|
25
android/apps/questInterface/proguard-rules.pro
vendored
Normal file
25
android/apps/questInterface/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in C:\Android\SDK/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
49
android/apps/questInterface/src/main/AndroidManifest.xml
Normal file
49
android/apps/questInterface/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="io.highfidelity.questInterface"
|
||||||
|
android:installLocation="auto">
|
||||||
|
|
||||||
|
<uses-feature android:glEsVersion="0x00030002" android:required="true" />
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
|
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true"/>
|
||||||
|
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true"/>
|
||||||
|
<uses-feature android:name="android.software.vr.mode" android:required="true"/>
|
||||||
|
<uses-feature android:name="android.hardware.vr.high_performance" android:required="true"/>
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name="org.qtproject.qt5.android.bindings.QtApplication"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:allowBackup="true">
|
||||||
|
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
||||||
|
<activity
|
||||||
|
android:name=".PermissionsChecker"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:excludeFromRecents="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.INFO" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
|
||||||
|
android:name=".InterfaceActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:launchMode="singleTask">
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="questInterface"/>
|
||||||
|
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||||
|
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so:lib/libQt5QuickParticles.so"/>
|
||||||
|
<meta-data android:name="android.app.background_running" android:value="false"/>
|
||||||
|
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
|
||||||
|
<meta-data android:name="android.app.extract_android_style" android:value="full"/>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
106
android/apps/questInterface/src/main/cpp/native.cpp
Normal file
106
android/apps/questInterface/src/main/cpp/native.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <QtCore/QBuffer>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include <QtAndroidExtras/QAndroidJniObject>
|
||||||
|
#include <QtAndroidExtras/QtAndroid>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <android/asset_manager.h>
|
||||||
|
#include <android/asset_manager_jni.h>
|
||||||
|
|
||||||
|
#include <shared/Storage.h>
|
||||||
|
|
||||||
|
#include <AddressManager.h>
|
||||||
|
#include <AndroidHelper.h>
|
||||||
|
#include <udt/PacketHeaders.h>
|
||||||
|
|
||||||
|
#include <OVR_Platform.h>
|
||||||
|
#include <OVR_Functions_Voip.h>
|
||||||
|
|
||||||
|
void initOculusPlatform(JNIEnv* env, jobject obj) {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&]{
|
||||||
|
// static const char* appID = "2343652845669354";
|
||||||
|
// if (ovr_PlatformInitializeAndroid(appID, obj, env) != ovrPlatformInitialize_Success) {
|
||||||
|
// __android_log_write(ANDROID_LOG_WARN, "QQQ", "Failed to init platform SDK");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// ovr_Voip_SetSystemVoipSuppressed(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void getClassName(JNIEnv *env, jobject obj){
|
||||||
|
jclass cls = env->GetObjectClass(obj);
|
||||||
|
jmethodID mid = env->GetMethodID(cls,"getClass", "()Ljava/lang/Class;");
|
||||||
|
jobject clsObj = env->CallObjectMethod(obj, mid);
|
||||||
|
|
||||||
|
cls= env->GetObjectClass(clsObj);
|
||||||
|
|
||||||
|
mid= env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
|
||||||
|
|
||||||
|
jstring strObj = (jstring) env->CallObjectMethod(clsObj, mid);
|
||||||
|
|
||||||
|
const char* str = env->GetStringUTFChars(strObj, NULL);
|
||||||
|
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR,__FUNCTION__, "Native Class call: %s",str);
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(strObj, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_nativeInitOculusPlatform(JNIEnv *env, jobject obj){
|
||||||
|
initOculusPlatform(env, obj);
|
||||||
|
}
|
||||||
|
QAndroidJniObject __interfaceActivity;
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnCreate(JNIEnv *env, jobject obj) {
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "QQQ", __FUNCTION__);
|
||||||
|
initOculusPlatform(env, obj);
|
||||||
|
getClassName(env, obj);
|
||||||
|
|
||||||
|
__interfaceActivity = QAndroidJniObject(obj);
|
||||||
|
|
||||||
|
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete, []() {
|
||||||
|
__interfaceActivity.callMethod<void>("onAppLoadedComplete", "()V");
|
||||||
|
|
||||||
|
QObject::disconnect(&AndroidHelper::instance(), &AndroidHelper::qtAppLoadComplete,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_oculus_OculusMobileActivity_questOnAppAfterLoad(JNIEnv* env, jobject obj) {
|
||||||
|
AndroidHelper::instance().moveToThread(qApp->thread());
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnPause(JNIEnv *env, jobject obj) {
|
||||||
|
AndroidHelper::instance().notifyEnterBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnResume(JNIEnv *env, jobject obj) {
|
||||||
|
AndroidHelper::instance().notifyEnterForeground();
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_io_highfidelity_questInterface_receiver_HeadsetStateReceiver_notifyHeadsetOn(JNIEnv *env,
|
||||||
|
jobject instance,
|
||||||
|
jboolean pluggedIn) {
|
||||||
|
AndroidHelper::instance().notifyHeadsetOn(pluggedIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.highfidelity.questInterface;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import io.highfidelity.oculus.OculusMobileActivity;
|
||||||
|
import io.highfidelity.utils.HifiUtils;
|
||||||
|
|
||||||
|
public class InterfaceActivity extends OculusMobileActivity {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
HifiUtils.upackAssets(getAssets(), getCacheDir().getAbsolutePath());
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package io.highfidelity.questInterface;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import io.highfidelity.oculus.OculusMobileActivity;
|
||||||
|
import io.highfidelity.utils.HifiUtils;
|
||||||
|
|
||||||
|
public class PermissionsChecker extends Activity {
|
||||||
|
private static final int REQUEST_PERMISSIONS = 20;
|
||||||
|
private static final String TAG = PermissionsChecker.class.getName();
|
||||||
|
private static final String[] REQUIRED_PERMISSIONS = new String[]{
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.RECORD_AUDIO,
|
||||||
|
Manifest.permission.CAMERA
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
requestAppPermissions(REQUIRED_PERMISSIONS,REQUEST_PERMISSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestAppPermissions(final String[] requestedPermissions,
|
||||||
|
final int requestCode) {
|
||||||
|
int permissionCheck = PackageManager.PERMISSION_GRANTED;
|
||||||
|
boolean shouldShowRequestPermissionRationale = false;
|
||||||
|
for (String permission : requestedPermissions) {
|
||||||
|
permissionCheck = permissionCheck + checkSelfPermission(permission);
|
||||||
|
shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale || shouldShowRequestPermissionRationale(permission);
|
||||||
|
}
|
||||||
|
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
System.out.println("Permission was not granted. Ask for permissions");
|
||||||
|
if (shouldShowRequestPermissionRationale) {
|
||||||
|
requestPermissions(requestedPermissions, requestCode);
|
||||||
|
} else {
|
||||||
|
requestPermissions(requestedPermissions, requestCode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Launching the other activity..");
|
||||||
|
launchActivityWithPermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchActivityWithPermissions() {
|
||||||
|
startActivity(new Intent(this, InterfaceActivity.class));
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
int permissionCheck = PackageManager.PERMISSION_GRANTED;
|
||||||
|
for (int permission : grantResults) {
|
||||||
|
permissionCheck = permissionCheck + permission;
|
||||||
|
}
|
||||||
|
if ((grantResults.length > 0) && permissionCheck == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
launchActivityWithPermissions();
|
||||||
|
} else if (grantResults.length > 0) {
|
||||||
|
System.out.println("User has deliberately denied Permissions. Launching anyways");
|
||||||
|
launchActivityWithPermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--suppress AndroidUnknownAttribute -->
|
||||||
|
<vector xmlns:api24="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:viewportWidth="192"
|
||||||
|
android:viewportHeight="192"
|
||||||
|
android:width="192dp"
|
||||||
|
android:height="192dp">
|
||||||
|
<path
|
||||||
|
android:pathData="M189.5 96.5A93.5 93.5 0 0 1 96 190 93.5 93.5 0 0 1 2.5 96.5 93.5 93.5 0 0 1 96 3 93.5 93.5 0 0 1 189.5 96.5Z"
|
||||||
|
android:fillColor="#333333" />
|
||||||
|
<path
|
||||||
|
android:pathData="M96.2 173.1c-10.3 0 -20.4 -2.1 -29.8 -6 -9.2 -3.8 -17.3 -9.4 -24.3 -16.4 -7 -7 -12.6 -15.2 -16.4 -24.3 -4.1 -9.6 -6.2 -19.6 -6.2 -30 0 -10.3 2.1 -20.4 6 -29.8 3.8 -9.2 9.4 -17.3 16.4 -24.3 7 -7 15.2 -12.6 24.3 -16.4 9.5 -4 19.5 -6 29.8 -6 10.3 0 20.4 2.1 29.8 6 9.2 3.8 17.3 9.4 24.3 16.4 7 7 12.6 15.2 16.4 24.3 4 9.5 6 19.5 6 29.8 0 10.3 -2.1 20.4 -6 29.8 -3.8 9.2 -9.4 17.3 -16.4 24.3 -7 7 -15.2 12.6 -24.3 16.4 -9.2 4.1 -19.3 6.2 -29.6 6.2zm0 -145.3c-37.8 0 -68.6 30.8 -68.6 68.6 0 37.8 30.8 68.6 68.6 68.6 37.8 0 68.6 -30.8 68.6 -68.6 0 -37.8 -30.8 -68.6 -68.6 -68.6z"
|
||||||
|
android:fillColor="#00b4f0" />
|
||||||
|
<path
|
||||||
|
android:pathData="M119.6 129l0 -53.8c3.4 -1.1 5.8 -4.3 5.8 -8 0 -4.6 -3.8 -8.4 -8.4 -8.4 -4.6 0 -8.4 3.8 -8.4 8.4 0 3.6 2.2 6.6 5.4 7.9l0 25L79 83.8 79 64c3.4 -1.1 5.8 -4.3 5.8 -8 0 -4.6 -3.8 -8.4 -8.4 -8.4 -4.6 0 -8.4 3.8 -8.4 8.4 0 3.6 2.2 6.6 5.4 7.9l0 54.1c-3.1 1.2 -5.4 4.3 -5.4 7.9 0 4.6 3.8 8.4 8.4 8.4 4.6 0 8.4 -3.8 8.4 -8.4 0 -3.7 -2.4 -6.9 -5.8 -8l0 -27.3 35 16.3 0 22.2c-3.1 1.2 -5.4 4.3 -5.4 7.9 0 4.6 3.8 8.4 8.4 8.4 4.6 0 8.4 -3.8 8.4 -8.4 0 -3.8 -2.4 -6.9 -5.8 -8z"
|
||||||
|
android:fillColor="#00b4f0" />
|
||||||
|
</vector>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">Interface</string>
|
||||||
|
</resources>
|
|
@ -42,6 +42,8 @@ ext {
|
||||||
RELEASE_TYPE = project.hasProperty('RELEASE_TYPE') ? project.getProperty('RELEASE_TYPE') : 'DEV'
|
RELEASE_TYPE = project.hasProperty('RELEASE_TYPE') ? project.getProperty('RELEASE_TYPE') : 'DEV'
|
||||||
STABLE_BUILD = project.hasProperty('STABLE_BUILD') ? project.getProperty('STABLE_BUILD') : '0'
|
STABLE_BUILD = project.hasProperty('STABLE_BUILD') ? project.getProperty('STABLE_BUILD') : '0'
|
||||||
EXEC_SUFFIX = Os.isFamily(Os.FAMILY_WINDOWS) ? '.exe' : ''
|
EXEC_SUFFIX = Os.isFamily(Os.FAMILY_WINDOWS) ? '.exe' : ''
|
||||||
|
appVersionCode = Integer.valueOf(VERSION_CODE ?: 1)
|
||||||
|
appVersionName = RELEASE_NUMBER ?: "1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
def appDir = new File(projectDir, 'apps/interface')
|
def appDir = new File(projectDir, 'apps/interface')
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
org.gradle.jvmargs=-Xms2g -Xmx4g
|
org.gradle.jvmargs=-Xms2g -Xmx4g
|
||||||
|
android.debug.obsoleteApi=true
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#Sat Dec 01 08:32:47 PST 2018
|
#Wed Dec 19 13:46:46 PST 2018
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||||
|
|
|
@ -15,3 +15,7 @@ android {
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(path: ':qt')
|
||||||
|
}
|
||||||
|
|
|
@ -7,62 +7,65 @@
|
||||||
//
|
//
|
||||||
package io.highfidelity.oculus;
|
package io.highfidelity.oculus;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
import android.view.WindowManager;
|
|
||||||
|
import org.qtproject.qt5.android.bindings.QtActivity;
|
||||||
|
import io.highfidelity.utils.HifiUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a native surface and forwards the activity lifecycle and surface lifecycle
|
* Contains a native surface and forwards the activity lifecycle and surface lifecycle
|
||||||
* events to the OculusMobileDisplayPlugin
|
* events to the OculusMobileDisplayPlugin
|
||||||
*/
|
*/
|
||||||
public class OculusMobileActivity extends Activity implements SurfaceHolder.Callback {
|
public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Callback {
|
||||||
private static final String TAG = OculusMobileActivity.class.getSimpleName();
|
private static final String TAG = OculusMobileActivity.class.getSimpleName();
|
||||||
static { System.loadLibrary("oculusMobile"); }
|
static { System.loadLibrary("oculusMobile"); }
|
||||||
|
|
||||||
private native void nativeOnCreate();
|
private native void nativeOnCreate();
|
||||||
private native static void nativeOnResume();
|
private native static void nativeOnResume();
|
||||||
private native static void nativeOnPause();
|
private native static void nativeOnPause();
|
||||||
private native static void nativeOnDestroy();
|
|
||||||
private native static void nativeOnSurfaceChanged(Surface s);
|
private native static void nativeOnSurfaceChanged(Surface s);
|
||||||
|
|
||||||
|
private native void questNativeOnCreate();
|
||||||
|
private native void questNativeOnPause();
|
||||||
|
private native void questNativeOnResume();
|
||||||
|
private native void questOnAppAfterLoad();
|
||||||
|
|
||||||
|
|
||||||
private SurfaceView mView;
|
private SurfaceView mView;
|
||||||
private SurfaceHolder mSurfaceHolder;
|
private SurfaceHolder mSurfaceHolder;
|
||||||
|
|
||||||
|
|
||||||
public static void launch(Activity activity) {
|
|
||||||
if (activity != null) {
|
|
||||||
activity.runOnUiThread(()->{
|
|
||||||
activity.startActivity(new Intent(activity, OculusMobileActivity.class));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
Log.w(TAG, "QQQ onCreate");
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
|
Log.w(TAG, "QQQ onCreate");
|
||||||
// Create a native surface for VR rendering (Qt GL surfaces are not suitable
|
// Create a native surface for VR rendering (Qt GL surfaces are not suitable
|
||||||
// because of the lack of fine control over the surface callbacks)
|
// because of the lack of fine control over the surface callbacks)
|
||||||
|
// Forward the create message to the JNI code
|
||||||
mView = new SurfaceView(this);
|
mView = new SurfaceView(this);
|
||||||
setContentView(mView);
|
|
||||||
mView.getHolder().addCallback(this);
|
mView.getHolder().addCallback(this);
|
||||||
|
|
||||||
// Forward the create message to the JNI code
|
|
||||||
nativeOnCreate();
|
nativeOnCreate();
|
||||||
|
questNativeOnCreate();
|
||||||
|
}
|
||||||
|
public void onAppLoadedComplete() {
|
||||||
|
Log.w(TAG, "QQQ Load Completed");
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
setContentView(mView);
|
||||||
|
questOnAppAfterLoad();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
Log.w(TAG, "QQQ onDestroy");
|
Log.w(TAG, "QQQ onDestroy");
|
||||||
if (mSurfaceHolder != null) {
|
|
||||||
nativeOnSurfaceChanged(null);
|
nativeOnSurfaceChanged(null);
|
||||||
}
|
|
||||||
nativeOnDestroy();
|
Log.w(TAG, "QQQ onDestroy -- SUPER onDestroy");
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,19 +73,38 @@ public class OculusMobileActivity extends Activity implements SurfaceHolder.Call
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
Log.w(TAG, "QQQ onResume");
|
Log.w(TAG, "QQQ onResume");
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
//Reconnect the global reference back to handler
|
||||||
|
nativeOnCreate();
|
||||||
|
|
||||||
|
questNativeOnResume();
|
||||||
nativeOnResume();
|
nativeOnResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
Log.w(TAG, "QQQ onPause");
|
Log.w(TAG, "QQQ onPause");
|
||||||
nativeOnPause();
|
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
|
questNativeOnPause();
|
||||||
|
nativeOnPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop(){
|
||||||
|
super.onStop();
|
||||||
|
Log.w(TAG, "QQQ Onstop called");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart(){
|
||||||
|
super.onRestart();
|
||||||
|
Log.w(TAG, "QQQ onRestart called ****");
|
||||||
|
questOnAppAfterLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
Log.w(TAG, "QQQ surfaceCreated");
|
Log.w(TAG, "QQQ surfaceCreated ************************************");
|
||||||
nativeOnSurfaceChanged(holder.getSurface());
|
nativeOnSurfaceChanged(holder.getSurface());
|
||||||
mSurfaceHolder = holder;
|
mSurfaceHolder = holder;
|
||||||
}
|
}
|
||||||
|
@ -96,8 +118,9 @@ public class OculusMobileActivity extends Activity implements SurfaceHolder.Call
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
Log.w(TAG, "QQQ surfaceDestroyed");
|
Log.w(TAG, "QQQ surfaceDestroyed ***************************************************");
|
||||||
nativeOnSurfaceChanged(null);
|
nativeOnSurfaceChanged(null);
|
||||||
mSurfaceHolder = null;
|
mSurfaceHolder = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -70,9 +70,6 @@ public class QtActivity extends Activity {
|
||||||
public final String QT_ANDROID_DEFAULT_THEME = QT_ANDROID_THEMES[0]; // sets the default theme.
|
public final String QT_ANDROID_DEFAULT_THEME = QT_ANDROID_THEMES[0]; // sets the default theme.
|
||||||
private QtActivityLoader m_loader = new QtActivityLoader(this);
|
private QtActivityLoader m_loader = new QtActivityLoader(this);
|
||||||
|
|
||||||
public boolean isLoading;
|
|
||||||
public boolean keepInterfaceRunning;
|
|
||||||
|
|
||||||
public QtActivity() {
|
public QtActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,10 +226,13 @@ public class QtActivity extends Activity {
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
protected void onCreateHook(Bundle savedInstanceState) {
|
protected void onCreateHook(Bundle savedInstanceState) {
|
||||||
|
|
||||||
m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS;
|
m_loader.APPLICATION_PARAMETERS = APPLICATION_PARAMETERS;
|
||||||
m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES;
|
m_loader.ENVIRONMENT_VARIABLES = ENVIRONMENT_VARIABLES;
|
||||||
m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES;
|
m_loader.QT_ANDROID_THEMES = QT_ANDROID_THEMES;
|
||||||
m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME;
|
m_loader.QT_ANDROID_DEFAULT_THEME = QT_ANDROID_DEFAULT_THEME;
|
||||||
|
|
||||||
|
|
||||||
m_loader.onCreate(savedInstanceState);
|
m_loader.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,10 @@ public class QtActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
QtApplication.invokeDelegate();
|
|
||||||
|
QtNative.terminateQt();
|
||||||
|
QtNative.setActivity(null,null);
|
||||||
|
System.exit(0);
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -506,9 +509,9 @@ public class QtActivity extends Activity {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
// GC: this trick allow us to show a splash activity until Qt app finishes
|
// GC: this trick allow us to show a splash activity until Qt app finishes
|
||||||
// loading
|
// loading
|
||||||
if (!isLoading && !keepInterfaceRunning) {
|
//QtApplication.invokeDelegate();
|
||||||
QtApplication.invokeDelegate();
|
|
||||||
}
|
//TODO(Amer): looking into why this messes up pause.
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -647,11 +650,7 @@ public class QtActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
if (!keepInterfaceRunning) {
|
QtApplication.invokeDelegate();
|
||||||
QtApplication.invokeDelegate();
|
|
||||||
}
|
|
||||||
QtNative.terminateQt();
|
|
||||||
QtNative.setActivity(null,null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -12,15 +12,26 @@ project(':qt').projectDir = new File(settingsDir, 'libraries/qt')
|
||||||
// Applications
|
// Applications
|
||||||
//
|
//
|
||||||
|
|
||||||
include ':interface'
|
if (!getSettings().hasProperty("SUPPRESS_INTERFACE")) {
|
||||||
project(':interface').projectDir = new File(settingsDir, 'apps/interface')
|
include ':interface'
|
||||||
|
project(':interface').projectDir = new File(settingsDir, 'apps/interface')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getSettings().hasProperty("SUPPRESS_QUEST_INTERFACE")) {
|
||||||
|
include ':questInterface'
|
||||||
|
project(':questInterface').projectDir = new File(settingsDir, 'apps/questInterface')
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Test projects
|
// Test projects
|
||||||
//
|
//
|
||||||
|
|
||||||
include ':framePlayer'
|
if (!getSettings().hasProperty("SUPPRESS_FRAME_PLAYER")) {
|
||||||
project(':framePlayer').projectDir = new File(settingsDir, 'apps/framePlayer')
|
include ':framePlayer'
|
||||||
|
project(':framePlayer').projectDir = new File(settingsDir, 'apps/framePlayer')
|
||||||
|
}
|
||||||
|
|
||||||
include ':questFramePlayer'
|
if (!getSettings().hasProperty("SUPPRESS_QUEST_FRAME_PLAYER")) {
|
||||||
project(':questFramePlayer').projectDir = new File(settingsDir, 'apps/questFramePlayer')
|
include ':questFramePlayer'
|
||||||
|
project(':questFramePlayer').projectDir = new File(settingsDir, 'apps/questFramePlayer')
|
||||||
|
}
|
||||||
|
|
|
@ -270,6 +270,16 @@ macro(AUTOSCRIBE_SHADER_LIBS)
|
||||||
set(AUTOSCRIBE_SHADERGEN_COMMANDS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shadergen.txt)
|
set(AUTOSCRIBE_SHADERGEN_COMMANDS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shadergen.txt)
|
||||||
file(WRITE ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE} "${AUTOSCRIBE_SHADERGEN_COMMANDS}")
|
file(WRITE ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE} "${AUTOSCRIBE_SHADERGEN_COMMANDS}")
|
||||||
|
|
||||||
|
if (HIFI_ANDROID)
|
||||||
|
if (
|
||||||
|
(${HIFI_ANDROID_APP} STREQUAL "questInterface") OR
|
||||||
|
(${HIFI_ANDROID_APP} STREQUAL "questFramePlayer") OR
|
||||||
|
(${HIFI_ANDROID_APP} STREQUAL "framePlayer")
|
||||||
|
)
|
||||||
|
set(EXTRA_SHADERGEN_ARGS --extensions EXT_clip_cull_distance)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# A custom python script which will generate all our shader artifacts
|
# A custom python script which will generate all our shader artifacts
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
||||||
|
@ -279,6 +289,7 @@ macro(AUTOSCRIBE_SHADER_LIBS)
|
||||||
--tools-dir ${VCPKG_TOOLS_DIR}
|
--tools-dir ${VCPKG_TOOLS_DIR}
|
||||||
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
--source-dir ${CMAKE_SOURCE_DIR}
|
--source-dir ${CMAKE_SOURCE_DIR}
|
||||||
|
${EXTRA_SHADERGEN_ARGS}
|
||||||
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
||||||
|
|
||||||
add_custom_target(shadergen DEPENDS ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS})
|
add_custom_target(shadergen DEPENDS ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS})
|
||||||
|
|
|
@ -53,9 +53,9 @@ ANDROID_PACKAGES = {
|
||||||
'includeLibs': ['libvrapi.so']
|
'includeLibs': ['libvrapi.so']
|
||||||
},
|
},
|
||||||
'oculusPlatform': {
|
'oculusPlatform': {
|
||||||
'file': 'OVRPlatformSDK_v1.32.0.zip',
|
'file': 'OVRPlatformSDK_v1.34.0.zip',
|
||||||
'versionId': 'jG9DB16zOGxSrmtZy4jcQnwO0TJUuaeL',
|
'versionId': 'vbRUkkyzUAXfTGSEtuiUr_7.Fm5h5BZk',
|
||||||
'checksum': 'ab5b203b3a39a56ab148d68fff769e05',
|
'checksum': '16e4c5f39520f122bc49cb6d5bb88289',
|
||||||
'sharedLibFolder': 'Android/libs/arm64-v8a',
|
'sharedLibFolder': 'Android/libs/arm64-v8a',
|
||||||
'includeLibs': ['libovrplatformloader.so']
|
'includeLibs': ['libovrplatformloader.so']
|
||||||
},
|
},
|
||||||
|
|
|
@ -425,11 +425,12 @@ FocusScope {
|
||||||
console.warn("Could not find top level window for " + item);
|
console.warn("Could not find top level window for " + item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (typeof Controller === "undefined") {
|
if (typeof Controller === "undefined") {
|
||||||
console.warn("Controller not yet available... can't center");
|
console.warn("Controller not yet available... can't center");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||||
|
@ -455,15 +456,17 @@ FocusScope {
|
||||||
console.warn("Could not find top level window for " + item);
|
console.warn("Could not find top level window for " + item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (typeof Controller === "undefined") {
|
if (typeof Controller === "undefined") {
|
||||||
console.warn("Controller not yet available... can't reposition targetWindow:" + targetWindow);
|
console.warn("Controller not yet available... can't reposition targetWindow:" + targetWindow);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||||
var newRecommendedRect = Controller.getRecommendedHUDRect();
|
var newRecommendedRect = { width: 1280, height: 720, x: 0, y: 0 };
|
||||||
|
if (typeof Controller !== "undefined") newRecommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||||
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
||||||
}
|
}
|
||||||
|
@ -480,7 +483,8 @@ FocusScope {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var recommended = Controller.getRecommendedHUDRect();
|
var recommended = { width: 1280, height: 720, x: 0, y: 0 };
|
||||||
|
if (typeof Controller !== "undefined") recommended = Controller.getRecommendedHUDRect();
|
||||||
var maxX = recommended.x + recommended.width;
|
var maxX = recommended.x + recommended.width;
|
||||||
var maxY = recommended.y + recommended.height;
|
var maxY = recommended.y + recommended.height;
|
||||||
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
||||||
|
|
|
@ -18,8 +18,8 @@ OriginalDesktop.Desktop {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
propagateComposedEvents: true
|
propagateComposedEvents: true
|
||||||
scrollGestureEnabled: false // we don't need/want these
|
scrollGestureEnabled: false // we don't need/want these
|
||||||
onEntered: ApplicationCompositor.reticleOverDesktop = true
|
onEntered: if (typeof ApplicationCompositor !== "undefined") ApplicationCompositor.reticleOverDesktop = true
|
||||||
onExited: ApplicationCompositor.reticleOverDesktop = false
|
onExited: if (typeof ApplicationCompositor !== "undefined") ApplicationCompositor.reticleOverDesktop = false
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -37,7 +38,6 @@
|
||||||
|
|
||||||
#include <QtNetwork/QLocalSocket>
|
#include <QtNetwork/QLocalSocket>
|
||||||
#include <QtNetwork/QLocalServer>
|
#include <QtNetwork/QLocalServer>
|
||||||
|
|
||||||
#include <QtQml/QQmlContext>
|
#include <QtQml/QQmlContext>
|
||||||
#include <QtQml/QQmlEngine>
|
#include <QtQml/QQmlEngine>
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
@ -51,6 +51,7 @@
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
|
|
||||||
|
|
||||||
#include <gl/QOpenGLContextWrapper.h>
|
#include <gl/QOpenGLContextWrapper.h>
|
||||||
#include <gl/GLWindow.h>
|
#include <gl/GLWindow.h>
|
||||||
#include <gl/GLHelpers.h>
|
#include <gl/GLHelpers.h>
|
||||||
|
@ -191,6 +192,9 @@
|
||||||
#include "scripting/WalletScriptingInterface.h"
|
#include "scripting/WalletScriptingInterface.h"
|
||||||
#include "scripting/TTSScriptingInterface.h"
|
#include "scripting/TTSScriptingInterface.h"
|
||||||
#include "scripting/KeyboardScriptingInterface.h"
|
#include "scripting/KeyboardScriptingInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
#include "SpeechRecognizer.h"
|
#include "SpeechRecognizer.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -239,6 +243,7 @@
|
||||||
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
||||||
#include <DesktopPreviewProvider.h>
|
#include <DesktopPreviewProvider.h>
|
||||||
|
|
||||||
|
|
||||||
#include "AboutUtil.h"
|
#include "AboutUtil.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
@ -1745,7 +1750,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
});
|
});
|
||||||
_applicationStateDevice->setInputVariant(STATE_PLATFORM_ANDROID, []() -> float {
|
_applicationStateDevice->setInputVariant(STATE_PLATFORM_ANDROID, []() -> float {
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
return 1;
|
return 1 ;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1848,6 +1853,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
|
|
||||||
this->installEventFilter(this);
|
this->installEventFilter(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_DDE
|
#ifdef HAVE_DDE
|
||||||
auto ddeTracker = DependencyManager::get<DdeFaceTracker>();
|
auto ddeTracker = DependencyManager::get<DdeFaceTracker>();
|
||||||
ddeTracker->init();
|
ddeTracker->init();
|
||||||
|
@ -3085,7 +3092,7 @@ void Application::initializeUi() {
|
||||||
}
|
}
|
||||||
if (TouchscreenVirtualPadDevice::NAME == inputPlugin->getName()) {
|
if (TouchscreenVirtualPadDevice::NAME == inputPlugin->getName()) {
|
||||||
_touchscreenVirtualPadDevice = std::dynamic_pointer_cast<TouchscreenVirtualPadDevice>(inputPlugin);
|
_touchscreenVirtualPadDevice = std::dynamic_pointer_cast<TouchscreenVirtualPadDevice>(inputPlugin);
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(ANDROID_APP_INTERFACE)
|
||||||
auto& virtualPadManager = VirtualPad::Manager::instance();
|
auto& virtualPadManager = VirtualPad::Manager::instance();
|
||||||
connect(&virtualPadManager, &VirtualPad::Manager::hapticFeedbackRequested,
|
connect(&virtualPadManager, &VirtualPad::Manager::hapticFeedbackRequested,
|
||||||
this, [](int duration) {
|
this, [](int duration) {
|
||||||
|
@ -3617,10 +3624,14 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get controller availability
|
// Get controller availability
|
||||||
|
#ifdef ANDROID_APP_QUEST_INTERFACE
|
||||||
|
bool hasHandControllers = true;
|
||||||
|
#else
|
||||||
bool hasHandControllers = false;
|
bool hasHandControllers = false;
|
||||||
if (PluginUtils::isViveControllerAvailable() || PluginUtils::isOculusTouchControllerAvailable()) {
|
if (PluginUtils::isViveControllerAvailable() || PluginUtils::isOculusTouchControllerAvailable()) {
|
||||||
hasHandControllers = true;
|
hasHandControllers = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check HMD use (may be technically available without being in use)
|
// Check HMD use (may be technically available without being in use)
|
||||||
bool hasHMD = PluginUtils::isHMDAvailable();
|
bool hasHMD = PluginUtils::isHMDAvailable();
|
||||||
|
@ -8237,6 +8248,7 @@ void Application::loadDomainConnectionDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::toggleLogDialog() {
|
void Application::toggleLogDialog() {
|
||||||
|
#ifndef ANDROID_APP_QUEST_INTERFACE
|
||||||
if (getLoginDialogPoppedUp()) {
|
if (getLoginDialogPoppedUp()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8260,6 +8272,7 @@ void Application::toggleLogDialog() {
|
||||||
} else {
|
} else {
|
||||||
_logDialog->show();
|
_logDialog->show();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::recreateLogWindow(int keepOnTop) {
|
void Application::recreateLogWindow(int keepOnTop) {
|
||||||
|
@ -9125,17 +9138,23 @@ void Application::beforeEnterBackground() {
|
||||||
void Application::enterBackground() {
|
void Application::enterBackground() {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
|
||||||
"stop", Qt::BlockingQueuedConnection);
|
"stop", Qt::BlockingQueuedConnection);
|
||||||
|
// Quest only supports one plugin which can't be deactivated currently
|
||||||
|
#if !defined(ANDROID_APP_QUEST_INTERFACE)
|
||||||
if (getActiveDisplayPlugin()->isActive()) {
|
if (getActiveDisplayPlugin()->isActive()) {
|
||||||
getActiveDisplayPlugin()->deactivate();
|
getActiveDisplayPlugin()->deactivate();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::enterForeground() {
|
void Application::enterForeground() {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
|
||||||
"start", Qt::BlockingQueuedConnection);
|
"start", Qt::BlockingQueuedConnection);
|
||||||
|
// Quest only supports one plugin which can't be deactivated currently
|
||||||
|
#if !defined(ANDROID_APP_QUEST_INTERFACE)
|
||||||
if (!getActiveDisplayPlugin() || getActiveDisplayPlugin()->isActive() || !getActiveDisplayPlugin()->activate()) {
|
if (!getActiveDisplayPlugin() || getActiveDisplayPlugin()->isActive() || !getActiveDisplayPlugin()->activate()) {
|
||||||
qWarning() << "Could not re-activate display plugin";
|
qWarning() << "Could not re-activate display plugin";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
nodeList->setSendDomainServerCheckInEnabled(true);
|
nodeList->setSendDomainServerCheckInEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,10 +388,23 @@ ShaderPointer Deserializer::readShader(const json& node) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, uint32_t> shadersIdsByName;
|
||||||
|
if (shadersIdsByName.empty()) {
|
||||||
|
for (const auto id : shader::allShaders()) {
|
||||||
|
const auto& shaderSource = shader::Source::get(id);
|
||||||
|
shadersIdsByName[shaderSource.name] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME support procedural shaders
|
// FIXME support procedural shaders
|
||||||
Shader::Type type = node[keys::type];
|
Shader::Type type = node[keys::type];
|
||||||
std::string name = node[keys::name];
|
std::string name = node[keys::name];
|
||||||
uint32_t id = node[keys::id];
|
// Using the serialized ID is bad, because it's generated at
|
||||||
|
// cmake time, and can change across platforms or when
|
||||||
|
// shaders are added or removed
|
||||||
|
// uint32_t id = node[keys::id];
|
||||||
|
|
||||||
|
uint32_t id = shadersIdsByName[name];
|
||||||
ShaderPointer result;
|
ShaderPointer result;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
//case Shader::Type::GEOMETRY:
|
//case Shader::Type::GEOMETRY:
|
||||||
|
|
|
@ -167,7 +167,7 @@ TransformObject getTransformObject() {
|
||||||
vec4 eyeClipEdge[2]= vec4[2](vec4(-1,0,0,1), vec4(1,0,0,1));
|
vec4 eyeClipEdge[2]= vec4[2](vec4(-1,0,0,1), vec4(1,0,0,1));
|
||||||
vec2 eyeOffsetScale = vec2(-0.5, +0.5);
|
vec2 eyeOffsetScale = vec2(-0.5, +0.5);
|
||||||
uint eyeIndex = uint(_stereoSide);
|
uint eyeIndex = uint(_stereoSide);
|
||||||
#ifndef GPU_GLES
|
#if !defined(GPU_GLES) || (defined(HAVE_EXT_clip_cull_distance) && !defined(VULKAN))
|
||||||
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
|
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
|
||||||
#endif
|
#endif
|
||||||
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
|
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
|
||||||
|
|
|
@ -315,10 +315,6 @@ JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_nativeOn
|
||||||
SURFACE.onCreate(env, obj);
|
SURFACE.onCreate(env, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_nativeOnDestroy(JNIEnv*, jclass) {
|
|
||||||
__android_log_write(ANDROID_LOG_WARN, "QQQ_JNI", __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_nativeOnResume(JNIEnv*, jclass) {
|
JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_nativeOnResume(JNIEnv*, jclass) {
|
||||||
__android_log_write(ANDROID_LOG_WARN, "QQQ_JNI", __FUNCTION__);
|
__android_log_write(ANDROID_LOG_WARN, "QQQ_JNI", __FUNCTION__);
|
||||||
SURFACE.setResumed(true);
|
SURFACE.setResumed(true);
|
||||||
|
|
7
libraries/render-utils/src/parabola_forward.slv
Normal file
7
libraries/render-utils/src/parabola_forward.slv
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
layout(location=0) in vec4 _color;
|
||||||
|
|
||||||
|
layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
_fragColor0 = _color;
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
#version 310 es
|
|
||||||
#define GPU_GLES
|
|
||||||
#define GPU_GLES_310
|
|
||||||
#define BITFIELD highp int
|
#define BITFIELD highp int
|
||||||
#define LAYOUT(X) layout(X)
|
#define LAYOUT(X) layout(X)
|
||||||
#define LAYOUT_STD140(X) layout(std140, X)
|
#define LAYOUT_STD140(X) layout(std140, X)
|
||||||
|
@ -9,6 +6,9 @@
|
||||||
#define gl_VertexID gl_VertexIndex
|
#define gl_VertexID gl_VertexIndex
|
||||||
#endif
|
#endif
|
||||||
#extension GL_EXT_texture_buffer : enable
|
#extension GL_EXT_texture_buffer : enable
|
||||||
|
#if defined(HAVE_EXT_clip_cull_distance) && !defined(VULKAN)
|
||||||
|
#extension GL_EXT_clip_cull_distance : enable
|
||||||
|
#endif
|
||||||
precision highp float;
|
precision highp float;
|
||||||
precision highp samplerBuffer;
|
precision highp samplerBuffer;
|
||||||
precision highp sampler2DShadow;
|
precision highp sampler2DShadow;
|
||||||
|
|
3
libraries/shaders/headers/310es/version.glsl
Normal file
3
libraries/shaders/headers/310es/version.glsl
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#version 310 es
|
||||||
|
#define GPU_GLES
|
||||||
|
#define GPU_GLES_310
|
|
@ -1,5 +1,3 @@
|
||||||
#version 410 core
|
|
||||||
#define GPU_GL410
|
|
||||||
#define BITFIELD int
|
#define BITFIELD int
|
||||||
#if defined(VULKAN)
|
#if defined(VULKAN)
|
||||||
#extension GL_ARB_shading_language_420pack : require
|
#extension GL_ARB_shading_language_420pack : require
|
||||||
|
|
2
libraries/shaders/headers/410/version.glsl
Normal file
2
libraries/shaders/headers/410/version.glsl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#version 410 core
|
||||||
|
#define GPU_GL410
|
|
@ -1,5 +1,3 @@
|
||||||
#version 450 core
|
|
||||||
#define GPU_GL450
|
|
||||||
#define GPU_SSBO_TRANSFORM_OBJECT
|
#define GPU_SSBO_TRANSFORM_OBJECT
|
||||||
#define BITFIELD int
|
#define BITFIELD int
|
||||||
#define LAYOUT(X) layout(X)
|
#define LAYOUT(X) layout(X)
|
||||||
|
|
2
libraries/shaders/headers/450/version.glsl
Normal file
2
libraries/shaders/headers/450/version.glsl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#version 450 core
|
||||||
|
#define GPU_GL450
|
|
@ -224,7 +224,7 @@ String Source::getSource(Dialect dialect, Variant variant) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#if defined(Q_OS_ANDROID) || defined(USE_GLES)
|
||||||
// SPIRV cross injects "#extension GL_OES_texture_buffer : require" into the GLSL shaders,
|
// SPIRV cross injects "#extension GL_OES_texture_buffer : require" into the GLSL shaders,
|
||||||
// which breaks android rendering
|
// which breaks android rendering
|
||||||
return variantSource.scribe;
|
return variantSource.scribe;
|
||||||
|
|
|
@ -24,7 +24,7 @@ QmlFragmentClass::QmlFragmentClass(bool restricted, QString id) : QmlWindowClass
|
||||||
|
|
||||||
// Method called by Qt scripts to create a new bottom menu bar in Android
|
// Method called by Qt scripts to create a new bottom menu bar in Android
|
||||||
QScriptValue QmlFragmentClass::internal_constructor(QScriptContext* context, QScriptEngine* engine, bool restricted) {
|
QScriptValue QmlFragmentClass::internal_constructor(QScriptContext* context, QScriptEngine* engine, bool restricted) {
|
||||||
|
#ifndef DISABLE_QML
|
||||||
std::lock_guard<std::mutex> guard(_mutex);
|
std::lock_guard<std::mutex> guard(_mutex);
|
||||||
auto qml = context->argument(0).toVariant().toMap().value("qml");
|
auto qml = context->argument(0).toVariant().toMap().value("qml");
|
||||||
if (qml.isValid()) {
|
if (qml.isValid()) {
|
||||||
|
@ -53,6 +53,9 @@ QScriptValue QmlFragmentClass::internal_constructor(QScriptContext* context, QSc
|
||||||
QScriptValue scriptObject = engine->newQObject(retVal);
|
QScriptValue scriptObject = engine->newQObject(retVal);
|
||||||
_fragments[qml.toString()] = scriptObject;
|
_fragments[qml.toString()] = scriptObject;
|
||||||
return scriptObject;
|
return scriptObject;
|
||||||
|
#else
|
||||||
|
return QScriptValue();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlFragmentClass::close() {
|
void QmlFragmentClass::close() {
|
||||||
|
@ -61,6 +64,7 @@ void QmlFragmentClass::close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* QmlFragmentClass::addButton(const QVariant& properties) {
|
QObject* QmlFragmentClass::addButton(const QVariant& properties) {
|
||||||
|
#ifndef DISABLE_QML
|
||||||
QVariant resultVar;
|
QVariant resultVar;
|
||||||
Qt::ConnectionType connectionType = Qt::AutoConnection;
|
Qt::ConnectionType connectionType = Qt::AutoConnection;
|
||||||
|
|
||||||
|
@ -79,8 +83,10 @@ QObject* QmlFragmentClass::addButton(const QVariant& properties) {
|
||||||
qWarning() << "QmlFragmentClass addButton result not a QObject";
|
qWarning() << "QmlFragmentClass addButton result not a QObject";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qmlButton;
|
return qmlButton;
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlFragmentClass::removeButton(QObject* button) {
|
void QmlFragmentClass::removeButton(QObject* button) {
|
||||||
|
|
|
@ -98,6 +98,7 @@ QmlWindowClass::QmlWindowClass(bool restricted) : _restricted(restricted) {
|
||||||
* @property {boolean} visible
|
* @property {boolean} visible
|
||||||
*/
|
*/
|
||||||
void QmlWindowClass::initQml(QVariantMap properties) {
|
void QmlWindowClass::initQml(QVariantMap properties) {
|
||||||
|
#ifndef DISABLE_QML
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
_source = properties[SOURCE_PROPERTY].toString();
|
_source = properties[SOURCE_PROPERTY].toString();
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ void QmlWindowClass::initQml(QVariantMap properties) {
|
||||||
|
|
||||||
Q_ASSERT(_qmlWindow);
|
Q_ASSERT(_qmlWindow);
|
||||||
Q_ASSERT(dynamic_cast<const QQuickItem*>(_qmlWindow.data()));
|
Q_ASSERT(dynamic_cast<const QQuickItem*>(_qmlWindow.data()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlWindowClass::qmlToScript(const QVariant& message) {
|
void QmlWindowClass::qmlToScript(const QVariant& message) {
|
||||||
|
|
|
@ -58,6 +58,9 @@ logging.setLoggerClass(TrackableLogger)
|
||||||
logger = logging.getLogger('prebuild')
|
logger = logging.getLogger('prebuild')
|
||||||
|
|
||||||
def headSha():
|
def headSha():
|
||||||
|
if shutil.which('git') is None:
|
||||||
|
logger.warn("Unable to find git executable, can't caclulate commit ID")
|
||||||
|
return '0xDEADBEEF'
|
||||||
repo_dir = os.path.dirname(os.path.abspath(__file__))
|
repo_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
git = subprocess.Popen(
|
git = subprocess.Popen(
|
||||||
'git rev-parse --short HEAD',
|
'git rev-parse --short HEAD',
|
||||||
|
@ -67,7 +70,7 @@ def headSha():
|
||||||
stdout, _ = git.communicate()
|
stdout, _ = git.communicate()
|
||||||
sha = stdout.split('\n')[0]
|
sha = stdout.split('\n')[0]
|
||||||
if not sha:
|
if not sha:
|
||||||
raise RuntimeError("couldn't find git sha")
|
raise RuntimeError("couldn't find git sha for repository {}".format(repo_dir))
|
||||||
return sha
|
return sha
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|
|
@ -49,11 +49,36 @@ def getCommonScribeArgs(scribefile, includeLibs):
|
||||||
scribeArgs.append(scribefile)
|
scribeArgs.append(scribefile)
|
||||||
return scribeArgs
|
return scribeArgs
|
||||||
|
|
||||||
def getDialectAndVariantHeaders(dialect, variant):
|
extensionsHeaderMutex = Lock()
|
||||||
|
|
||||||
|
def getExtensionsHeader(dialect, variant, extensions):
|
||||||
|
extensionHeader = '{}/extensions_{}_{}.glsl'.format(args.build_dir, dialect, variant)
|
||||||
|
global extensionsHeaderMutex
|
||||||
|
extensionsHeaderMutex.acquire()
|
||||||
|
if not os.path.exists(extensionHeader):
|
||||||
|
extensionsDefines = []
|
||||||
|
for extension in extensions:
|
||||||
|
extensionsDefines.append('#define HAVE_{}'.format(extension))
|
||||||
|
# make sure we end with a line feed
|
||||||
|
extensionsDefines.append("\r\n")
|
||||||
|
with open(extensionHeader, "w") as f:
|
||||||
|
f.write('\r\n'.join(extensionsDefines))
|
||||||
|
extensionsHeaderMutex.release()
|
||||||
|
return extensionHeader
|
||||||
|
|
||||||
|
|
||||||
|
def getDialectAndVariantHeaders(dialect, variant, extensions=None):
|
||||||
|
result = []
|
||||||
headerPath = args.source_dir + '/libraries/shaders/headers/'
|
headerPath = args.source_dir + '/libraries/shaders/headers/'
|
||||||
variantHeader = headerPath + ('stereo.glsl' if (variant == 'stereo') else 'mono.glsl')
|
versionHeader = headerPath + dialect + '/version.glsl'
|
||||||
|
result.append(versionHeader)
|
||||||
|
if extensions is not None:
|
||||||
|
result.append(getExtensionsHeader(dialect, variant, extensions))
|
||||||
dialectHeader = headerPath + dialect + '/header.glsl'
|
dialectHeader = headerPath + dialect + '/header.glsl'
|
||||||
return [dialectHeader, variantHeader]
|
result.append(dialectHeader)
|
||||||
|
variantHeader = headerPath + ('stereo.glsl' if (variant == 'stereo') else 'mono.glsl')
|
||||||
|
result.append(variantHeader)
|
||||||
|
return result
|
||||||
|
|
||||||
class ScribeDependenciesCache:
|
class ScribeDependenciesCache:
|
||||||
cache = {}
|
cache = {}
|
||||||
|
@ -170,7 +195,7 @@ def processCommand(line):
|
||||||
|
|
||||||
scribeDepCache.gen(scribeFile, libs, dialect, variant)
|
scribeDepCache.gen(scribeFile, libs, dialect, variant)
|
||||||
scribeArgs = getCommonScribeArgs(scribeFile, libs)
|
scribeArgs = getCommonScribeArgs(scribeFile, libs)
|
||||||
for header in getDialectAndVariantHeaders(dialect, variant):
|
for header in getDialectAndVariantHeaders(dialect, variant, args.extensions):
|
||||||
scribeArgs.extend(['-H', header])
|
scribeArgs.extend(['-H', header])
|
||||||
scribeArgs.extend(['-o', unoptGlslFile])
|
scribeArgs.extend(['-o', unoptGlslFile])
|
||||||
executeSubprocess(scribeArgs)
|
executeSubprocess(scribeArgs)
|
||||||
|
@ -218,6 +243,7 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
parser = ArgumentParser(description='Generate shader artifacts.')
|
parser = ArgumentParser(description='Generate shader artifacts.')
|
||||||
|
parser.add_argument('--extensions', type=str, nargs='*', help='Available extensions for the shaders')
|
||||||
parser.add_argument('--commands', type=argparse.FileType('r'), help='list of commands to execute')
|
parser.add_argument('--commands', type=argparse.FileType('r'), help='list of commands to execute')
|
||||||
parser.add_argument('--tools-dir', type=str, help='location of the host compatible binaries')
|
parser.add_argument('--tools-dir', type=str, help='location of the host compatible binaries')
|
||||||
parser.add_argument('--build-dir', type=str, help='The build directory base path')
|
parser.add_argument('--build-dir', type=str, help='The build directory base path')
|
||||||
|
@ -230,8 +256,8 @@ args = None
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
# for debugging
|
# for debugging
|
||||||
sourceDir = expanduser('~/git/hifi')
|
sourceDir = expanduser('~/git/hifi')
|
||||||
toolsDir = os.path.join(expanduser('~/git/vcpkg'), 'installed', 'x64-windows', 'tools')
|
toolsDir = 'd:/hifi/vcpkg/android/fd82f0a8/installed/x64-windows/tools'
|
||||||
buildPath = sourceDir + '/build'
|
buildPath = sourceDir + '/build_android'
|
||||||
commandsPath = buildPath + '/libraries/shaders/shadergen.txt'
|
commandsPath = buildPath + '/libraries/shaders/shadergen.txt'
|
||||||
shaderDir = buildPath + '/libraries/shaders'
|
shaderDir = buildPath + '/libraries/shaders'
|
||||||
testArgs = '--commands {} --tools-dir {} --build-dir {} --source-dir {}'.format(
|
testArgs = '--commands {} --tools-dir {} --build-dir {} --source-dir {}'.format(
|
||||||
|
@ -239,6 +265,7 @@ if len(sys.argv) == 1:
|
||||||
).split()
|
).split()
|
||||||
testArgs.append('--debug')
|
testArgs.append('--debug')
|
||||||
testArgs.append('--force')
|
testArgs.append('--force')
|
||||||
|
testArgs.extend('--extensions EXT_clip_cull_distance'.split())
|
||||||
#testArgs.append('--dry-run')
|
#testArgs.append('--dry-run')
|
||||||
args = parser.parse_args(testArgs)
|
args = parser.parse_args(testArgs)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue