mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
merge with master
This commit is contained in:
commit
13ece79476
144 changed files with 681 additions and 193 deletions
|
@ -81,6 +81,25 @@ if (ANDROID)
|
|||
set(GLES_OPTION ON)
|
||||
set(PLATFORM_QT_COMPONENTS AndroidExtras WebView)
|
||||
add_definitions(-DHIFI_ANDROID_APP=\"${HIFI_ANDROID_APP}\")
|
||||
if (
|
||||
(${HIFI_ANDROID_APP} STREQUAL "questInterface") OR
|
||||
(${HIFI_ANDROID_APP} STREQUAL "questFramePlayer") OR
|
||||
(${HIFI_ANDROID_APP} STREQUAL "framePlayer")
|
||||
)
|
||||
# We know the quest hardware has this extension, so we can force the use of instanced stereo
|
||||
add_definitions(-DHAVE_EXT_clip_cull_distance)
|
||||
# We can also use multiview stereo techniques
|
||||
add_definitions(-DHAVE_OVR_multiview2)
|
||||
add_definitions(-DHAVE_OVR_multiview)
|
||||
# We can also use our own foveated textures
|
||||
add_definitions(-DHAVE_QCOM_texture_foveated)
|
||||
|
||||
# if set, the application itself or some library it depends on MUST implement
|
||||
# `DisplayPluginList getDisplayPlugins()` and `InputPluginList getInputPlugins()`
|
||||
add_definitions(-DCUSTOM_INPUT_PLUGINS)
|
||||
add_definitions(-DCUSTOM_DISPLAY_PLUGINS)
|
||||
set(PLATFORM_PLUGIN_LIBRARIES oculusMobile oculusMobilePlugin)
|
||||
endif()
|
||||
else ()
|
||||
set(PLATFORM_QT_COMPONENTS WebEngine Xml)
|
||||
endif ()
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
import com.android.builder.core.BuilderConstants
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
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 : ''
|
||||
}
|
||||
}
|
||||
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "io.highfidelity.frameplayer"
|
||||
|
@ -32,19 +25,17 @@ android {
|
|||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
externalNativeBuild.cmake.path '../../../CMakeLists.txt'
|
||||
|
||||
variantFilter { variant ->
|
||||
def build = variant.buildType.name
|
||||
if (build == BuilderConstants.RELEASE) {
|
||||
variant.setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild.cmake.path '../../../CMakeLists.txt'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: '../../libraries/qt/libs')
|
||||
//implementation project(':oculus')
|
||||
implementation project(':qt')
|
||||
}
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
import com.android.builder.core.BuilderConstants
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
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 : ''
|
||||
}
|
||||
}
|
||||
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "io.highfidelity.frameplayer"
|
||||
|
@ -33,15 +26,14 @@ android {
|
|||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
externalNativeBuild.cmake.path '../../../CMakeLists.txt'
|
||||
|
||||
variantFilter { variant ->
|
||||
def build = variant.buildType.name
|
||||
if (build == BuilderConstants.RELEASE) {
|
||||
variant.setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild.cmake.path '../../../CMakeLists.txt'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -650,6 +650,8 @@ public class QtActivity extends Activity {
|
|||
if (!keepInterfaceRunning) {
|
||||
QtApplication.invokeDelegate();
|
||||
}
|
||||
QtNative.terminateQt();
|
||||
QtNative.setActivity(null,null);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -211,7 +211,10 @@ link_hifi_libraries(
|
|||
render-utils entities-renderer avatars-renderer ui qml auto-updater midi
|
||||
controllers plugins image trackers
|
||||
ui-plugins display-plugins input-plugins
|
||||
# Platform specific GL libraries
|
||||
${PLATFORM_GL_BACKEND}
|
||||
# Plaform specific input & display plugin libraries
|
||||
${PLATFORM_PLUGIN_LIBRARIES}
|
||||
shaders
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ Rectangle {
|
|||
HifiControlsUit.Keyboard {
|
||||
id: keyboard
|
||||
z: 1000
|
||||
raised: parent.keyboardEnabled && parent.keyboardRaised
|
||||
raised: parent.keyboardEnabled && parent.keyboardRaised && HMD.active
|
||||
numeric: parent.punctuationMode
|
||||
anchors {
|
||||
left: parent.left
|
||||
|
|
|
@ -607,7 +607,7 @@ Rectangle {
|
|||
} else if (msg.method === "showTrashLightbox") {
|
||||
lightboxPopup.titleText = "Send \"" + msg.itemName + "\" to Trash";
|
||||
lightboxPopup.bodyText = "Sending this item to the Trash means you will no longer own this item " +
|
||||
"and it will be inaccessible to you from Purchases.\n\nThis action cannot be undone.";
|
||||
"and it will be inaccessible to you from Inventory.\n\nThis action cannot be undone.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
*
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {string} buildDate
|
||||
* @property {string} buildVersion
|
||||
* @property {string} qtVersion
|
||||
|
|
|
@ -603,8 +603,9 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
|||
__android_log_write(ANDROID_LOG_FATAL,"Interface",local);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
qApp->getLogger()->addMessage(qPrintable(logMessage));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -989,7 +990,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
QApplication(argc, argv),
|
||||
_window(new MainWindow(desktop())),
|
||||
_sessionRunTimer(startupTimer),
|
||||
#ifndef Q_OS_ANDROID
|
||||
_logger(new FileLogger(this)),
|
||||
#endif
|
||||
_previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)),
|
||||
_entitySimulation(new PhysicalEntitySimulation()),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
|
@ -1123,7 +1126,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
_logger->setSessionID(accountManager->getSessionID());
|
||||
#endif
|
||||
|
||||
setCrashAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString());
|
||||
setCrashAnnotation("main_thread_id", std::to_string((size_t)QThread::currentThreadId()));
|
||||
|
@ -4963,7 +4968,11 @@ void Application::idle() {
|
|||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||
// details normally.
|
||||
#ifdef Q_OS_ANDROID
|
||||
bool showWarnings = false;
|
||||
#else
|
||||
bool showWarnings = getLogger()->extraDebugging();
|
||||
#endif
|
||||
PerformanceWarning warn(showWarnings, "idle()");
|
||||
|
||||
{
|
||||
|
@ -8306,7 +8315,7 @@ void Application::toggleLogDialog() {
|
|||
bool keepOnTop =_keepLogWindowOnTop.get();
|
||||
#ifdef Q_OS_WIN
|
||||
_logDialog = new LogDialog(keepOnTop ? qApp->getWindow() : nullptr, getLogger());
|
||||
#else
|
||||
#elif !defined(Q_OS_ANDROID)
|
||||
_logDialog = new LogDialog(nullptr, getLogger());
|
||||
|
||||
if (keepOnTop) {
|
||||
|
|
|
@ -251,7 +251,9 @@ public:
|
|||
|
||||
void setActiveDisplayPlugin(const QString& pluginName);
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
FileLogger* getLogger() const { return _logger; }
|
||||
#endif
|
||||
|
||||
float getRenderResolutionScale() const;
|
||||
|
||||
|
@ -599,7 +601,9 @@ private:
|
|||
|
||||
bool _aboutToQuit { false };
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
FileLogger* _logger { nullptr };
|
||||
#endif
|
||||
|
||||
bool _previousSessionCrashed;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class AABox;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} presentTime <em>Read-only.</em>
|
||||
* @property {number} engineRunTime <em>Read-only.</em>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* @hifi-client-entity
|
||||
* @hifi-interface
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class LocationBookmarks : public Bookmarks, public Dependency {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
class SpeechRecognizer : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -31,6 +31,7 @@ class AudioScope : public QObject, public Dependency {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} scopeInput <em>Read-only.</em>
|
||||
* @property {number} scopeOutputLeft <em>Read-only.</em>
|
||||
|
|
|
@ -46,6 +46,7 @@ using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @borrows AvatarList.getAvatarIdentifiers as getAvatarIdentifiers
|
||||
* @borrows AvatarList.getAvatarsInRange as getAvatarsInRange
|
||||
|
|
|
@ -66,6 +66,7 @@ class MyAvatar : public Avatar {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {Vec3} qmlPosition - A synonym for <code>position</code> for use by QML.
|
||||
* @property {boolean} shouldRenderLocally=true - If <code>true</code> then your avatar is rendered for you in Interface,
|
||||
|
|
|
@ -447,6 +447,10 @@ void OtherAvatar::handleChangedAvatarEntityData() {
|
|||
EntityItemProperties properties;
|
||||
int32_t bytesLeftToRead = data.size();
|
||||
unsigned char* dataAt = (unsigned char*)(data.data());
|
||||
// FIXME: This function will cause unintented changes in SpaillyNestable
|
||||
// E.g overriding the ID index of an exisiting entity to temporary entity
|
||||
// in the following map QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
||||
// Andrew Meadows will address this issue
|
||||
if (!properties.constructFromBuffer(dataAt, bytesLeftToRead)) {
|
||||
// properties are corrupt
|
||||
continue;
|
||||
|
@ -489,6 +493,17 @@ void OtherAvatar::handleChangedAvatarEntityData() {
|
|||
bool success = true;
|
||||
if (entity) {
|
||||
QUuid oldParentID = entity->getParentID();
|
||||
|
||||
// Since has overwrtiiten the back pointer
|
||||
// from the parent children map (see comment for function call above),
|
||||
// we need to for reset the back pointer in the map correctly by setting the parentID, but
|
||||
// since the parentID of the entity has not changed we first need to set it some ither ID,
|
||||
// then set the the original ID for the changes to take effect
|
||||
// TODO: This is a horrible hack and once properties.constructFromBuffer no longer causes
|
||||
// side effects...remove the following three lines
|
||||
const QUuid NULL_ID = QUuid("{00000000-0000-0000-0000-000000000005}");
|
||||
entity->setParentID(NULL_ID);
|
||||
entity->setParentID(oldParentID);
|
||||
if (entityTree->updateEntity(entityID, properties)) {
|
||||
entity->updateLastEditedFromRemote();
|
||||
} else {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class DdeFaceTracker : public FaceTracker, public Dependency {
|
||||
|
|
|
@ -38,11 +38,13 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
|
|||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"OctreePacketProcessor::processPacket()");
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
const int WAY_BEHIND = 300;
|
||||
|
||||
if (packetsToProcessCount() > WAY_BEHIND && qApp->getLogger()->extraDebugging()) {
|
||||
qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wasStatsPacket = false;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
public:
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} PICK_ENTITIES A filter flag. Include domain and avatar entities when intersecting. <em>Read-only.</em>. Deprecated.
|
||||
* @property {number} PICK_OVERLAYS A filter flag. Include local entities when intersecting. <em>Read-only.</em>. Deprecated.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class PointerScriptingInterface : public QObject, public Dependency {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} PICK_ENTITIES <em>Read-only.</em>
|
||||
* @property {number} PICK_OVERLAYS <em>Read-only.</em>
|
||||
|
|
|
@ -42,6 +42,7 @@ class AccountServicesScriptingInterface : public QObject {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @namespace AccountServices
|
||||
* @property {string} username <em>Read-only.</em>
|
||||
|
|
|
@ -32,6 +32,7 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
class ClipboardScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -199,6 +199,7 @@ class ScriptEngine;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
||||
* points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
*
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {number} ALWAYS_ON_TOP - InteractiveWindow flag for always showing a window on top
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class GooglePolyScriptingInterface : public QObject, public Dependency {
|
||||
|
|
|
@ -31,6 +31,7 @@ class QScriptEngine;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise
|
||||
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {bool} raised - <code>true</code> If the keyboard is visible <code>false</code> otherwise
|
||||
* @property {bool} password - <code>true</code> Will show * instead of characters in the text display <code>false</code> otherwise
|
||||
|
|
|
@ -35,6 +35,7 @@ class MenuItemProperties;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @example <caption>Outline an entity when it is grabbed by a controller.</caption>
|
||||
* // Create a box and copy the following text into the entity's "Script URL" field.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class SettingsScriptingInterface : public QObject {
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} walletStatus
|
||||
* @property {bool} limitedCommerce
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other
|
||||
* chrome), in pixels. <em>Read-only.</em>
|
||||
|
|
|
@ -29,6 +29,7 @@ class AvatarInputs : public QObject {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {boolean} cameraEnabled <em>Read-only.</em>
|
||||
* @property {boolean} cameraMuted <em>Read-only.</em>
|
||||
|
|
|
@ -42,6 +42,7 @@ private:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class Snapshot : public QObject, public Dependency {
|
||||
|
|
|
@ -27,6 +27,7 @@ private: \
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {Uuid} keyboardFocusOverlay - Get or set the {@link Overlays.OverlayType|web3d} overlay that has keyboard focus.
|
||||
* If no overlay has keyboard focus, get returns <code>null</code>; set to <code>null</code> or {@link Uuid|Uuid.NULL} to
|
||||
|
|
|
@ -4,5 +4,6 @@ link_hifi_libraries(shared graphics fbx)
|
|||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(gpu)
|
||||
include_hifi_library_headers(hfm)
|
||||
include_hifi_library_headers(image)
|
||||
|
||||
target_nsight()
|
||||
|
|
|
@ -50,6 +50,7 @@ Q_DECLARE_METATYPE(AnimationPointer)
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -30,6 +30,7 @@ class AnimationCacheScriptingInterface : public ScriptableResourceCache, public
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||
|
|
|
@ -44,6 +44,7 @@ class AudioStreamStatsInterface : public QObject {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} lossRate <em>Read-only.</em>
|
||||
* @property {number} lossCount <em>Read-only.</em>
|
||||
|
@ -192,6 +193,7 @@ class AudioStatsInterface : public QObject {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} pingMs <em>Read-only.</em>
|
||||
* @property {number} inputReadMsMax <em>Read-only.</em>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef QSharedPointer<Sound> SharedSoundPointer;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -30,6 +30,7 @@ class SoundCacheScriptingInterface : public ScriptableResourceCache, public Depe
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -107,10 +107,11 @@ int ClientTraitsHandler::sendChangedTraitsToMixer() {
|
|||
|
||||
if (initialSend || *simpleIt == Updated) {
|
||||
if (traitType == AvatarTraits::SkeletonModelURL) {
|
||||
bytesWritten += _owningAvatar->packTrait(traitType, *traitsPacketList);
|
||||
|
||||
// keep track of our skeleton version in case we get an override back
|
||||
_currentSkeletonVersion = _currentTraitVersion;
|
||||
}
|
||||
bytesWritten += _owningAvatar->packTrait(traitType, *traitsPacketList);
|
||||
}
|
||||
|
||||
++simpleIt;
|
||||
|
|
|
@ -154,7 +154,7 @@ void TextureBaker::processTexture() {
|
|||
gpu::BackendTarget::GLES32
|
||||
}};
|
||||
for (auto target : BACKEND_TARGETS) {
|
||||
auto processedTexture = image::processImage(buffer, _textureURL.toString().toStdString(),
|
||||
auto processedTexture = image::processImage(buffer, _textureURL.toString().toStdString(), image::ColorChannel::NONE,
|
||||
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, true,
|
||||
target, _abortProcessing);
|
||||
if (!processedTexture) {
|
||||
|
@ -197,7 +197,7 @@ void TextureBaker::processTexture() {
|
|||
// Uncompressed KTX
|
||||
if (_textureType == image::TextureUsage::Type::CUBE_TEXTURE) {
|
||||
buffer->reset();
|
||||
auto processedTexture = image::processImage(std::move(buffer), _textureURL.toString().toStdString(),
|
||||
auto processedTexture = image::processImage(std::move(buffer), _textureURL.toString().toStdString(), image::ColorChannel::NONE,
|
||||
ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, _textureType, false, gpu::BackendTarget::GL45, _abortProcessing);
|
||||
if (!processedTexture) {
|
||||
handleError("Could not process texture " + _textureURL.toString());
|
||||
|
|
|
@ -57,6 +57,7 @@ class UserInputMapper;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
|
|
|
@ -39,6 +39,7 @@ class ScriptingInterface;
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
// TODO migrate functionality to a RouteBuilder class and make the proxy defer to that
|
||||
|
|
|
@ -178,6 +178,7 @@ private:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {boolean} allowMouseCapture
|
||||
* @property {number} depth
|
||||
|
|
|
@ -20,6 +20,7 @@ const QString& DisplayPlugin::MENU_PATH() {
|
|||
return value;
|
||||
}
|
||||
|
||||
#if !defined(CUSTOM_DISPLAY_PLUGINS)
|
||||
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
||||
DisplayPluginList getDisplayPlugins() {
|
||||
DisplayPlugin* PLUGIN_POOL[] = {
|
||||
|
@ -49,3 +50,4 @@ DisplayPluginList getDisplayPlugins() {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
|
@ -720,6 +720,8 @@ void OpenGLDisplayPlugin::present() {
|
|||
}
|
||||
|
||||
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
|
||||
} else {
|
||||
internalPresent();
|
||||
}
|
||||
_movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent));
|
||||
}
|
||||
|
|
|
@ -51,15 +51,15 @@ bool DebugHmdDisplayPlugin::internalActivate() {
|
|||
}, true, _isAutoRotateEnabled);
|
||||
|
||||
_ipd = 0.0327499993f * 2.0f;
|
||||
// Would be nice to know why the left and right projection matrices are slightly dissymetrical
|
||||
_eyeProjections[0][0] = vec4{ 0.759056330, 0.000000000, 0.000000000, 0.000000000 };
|
||||
_eyeProjections[0][1] = vec4{ 0.000000000, 0.682773232, 0.000000000, 0.000000000 };
|
||||
_eyeProjections[0][2] = vec4{ -0.0580431037, -0.00619550655, -1.00000489, -1.00000000 };
|
||||
_eyeProjections[0][3] = vec4{ 0.000000000, 0.000000000, -0.0800003856, 0.000000000 };
|
||||
_eyeProjections[1][0] = vec4{ 0.752847493, 0.000000000, 0.000000000, 0.000000000 };
|
||||
_eyeProjections[1][1] = vec4{ 0.000000000, 0.678060353, 0.000000000, 0.000000000 };
|
||||
_eyeProjections[1][2] = vec4{ 0.0578232110, -0.00669418881, -1.00000489, -1.000000000 };
|
||||
_eyeProjections[1][3] = vec4{ 0.000000000, 0.000000000, -0.0800003856, 0.000000000 };
|
||||
// Quest
|
||||
_eyeProjections[0][0] = vec4{ 0.91729, 0.0, -0.17407, 0.0 };
|
||||
_eyeProjections[0][1] = vec4{ 0.0, 0.083354, -0.106141, 0.0 };
|
||||
_eyeProjections[0][2] = vec4{ 0.0, 0.0, -1.0, -0.2 };
|
||||
_eyeProjections[0][3] = vec4{ 0.0, 0.0, -1.0, 0.0 };
|
||||
_eyeProjections[1][0] = vec4{ 0.91729, 0.0, 0.17407, 0.0 };
|
||||
_eyeProjections[1][1] = vec4{ 0.0, 0.083354, -0.106141, 0.0 };
|
||||
_eyeProjections[1][2] = vec4{ 0.0, 0.0, -1.0, -0.2 };
|
||||
_eyeProjections[1][3] = vec4{ 0.0, 0.0, -1.0, 0.0 };
|
||||
// No need to do so here as this will done in Parent::internalActivate
|
||||
//_eyeInverseProjections[0] = glm::inverse(_eyeProjections[0]);
|
||||
//_eyeInverseProjections[1] = glm::inverse(_eyeProjections[1]);
|
||||
|
|
|
@ -81,7 +81,6 @@ protected:
|
|||
mat4 presentPose;
|
||||
double sensorSampleTime { 0 };
|
||||
double predictedDisplayTime { 0 };
|
||||
mat3 presentReprojection;
|
||||
};
|
||||
|
||||
QMap<uint32_t, FrameInfo> _frameInfos;
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <NetworkAccessManager.h>
|
||||
#include <ResourceManager.h>
|
||||
#include <PathUtils.h>
|
||||
#include <image/ColorChannel.h>
|
||||
|
||||
#include "FBXSerializer.h"
|
||||
|
||||
|
@ -1146,8 +1147,10 @@ void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& mat
|
|||
}
|
||||
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
|
||||
fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||
fbxmat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN;
|
||||
fbxmat.useRoughnessMap = true;
|
||||
fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||
fbxmat.metallicTexture.sourceChannel = image::ColorChannel::BLUE;
|
||||
fbxmat.useMetallicMap = true;
|
||||
}
|
||||
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
||||
|
|
|
@ -418,6 +418,10 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
#if defined(GPU_STEREO_DRAWCALL_INSTANCED) && !defined(GL_CLIP_DISTANCE0)
|
||||
#define GL_CLIP_DISTANCE0 GL_CLIP_DISTANCE0_EXT
|
||||
#endif
|
||||
|
||||
#define GL_PROFILE_RANGE(category, name) \
|
||||
PROFILE_RANGE(category, name); \
|
||||
GlDuration glProfileRangeThis(name);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
// Different versions for the stereo drawcall
|
||||
// Current preferred is "instanced" which draw the shape twice but instanced and rely on clipping plane to draw left/right side only
|
||||
#if defined(USE_GLES)
|
||||
#if defined(USE_GLES) && !defined(HAVE_EXT_clip_cull_distance)
|
||||
#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
|
||||
#else
|
||||
//#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
|
||||
|
|
|
@ -60,9 +60,17 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
|||
switch (texture.getType()) {
|
||||
case Texture::TEX_2D:
|
||||
if (!texture.isArray()) {
|
||||
return GL_TEXTURE_2D;
|
||||
if (!texture.isMultisample()) {
|
||||
return GL_TEXTURE_2D;
|
||||
} else {
|
||||
return GL_TEXTURE_2D_MULTISAMPLE;
|
||||
}
|
||||
} else {
|
||||
return GL_TEXTURE_2D_ARRAY;
|
||||
if (!texture.isMultisample()) {
|
||||
return GL_TEXTURE_2D_ARRAY;
|
||||
} else {
|
||||
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -81,7 +89,9 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
|||
uint8_t GLTexture::getFaceCount(GLenum target) {
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
return TEXTURE_2D_NUM_FACES;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
return TEXTURE_CUBE_NUM_FACES;
|
||||
|
@ -96,15 +106,20 @@ const std::vector<GLenum>& GLTexture::getFaceTargets(GLenum target) {
|
|||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||
};
|
||||
static const std::vector<GLenum> faceTargets {
|
||||
static const std::vector<GLenum> face2DTargets {
|
||||
GL_TEXTURE_2D
|
||||
};
|
||||
static const std::vector<GLenum> arrayFaceTargets{
|
||||
static const std::vector<GLenum> face2DMSTargets{
|
||||
GL_TEXTURE_2D_MULTISAMPLE
|
||||
};
|
||||
static const std::vector<GLenum> arrayFaceTargets{
|
||||
GL_TEXTURE_2D_ARRAY
|
||||
};
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
return faceTargets;
|
||||
return face2DTargets;
|
||||
case GL_TEXTURE_2D_MULTISAMPLE:
|
||||
return face2DMSTargets;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
return arrayFaceTargets;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
|
@ -114,7 +129,7 @@ const std::vector<GLenum>& GLTexture::getFaceTargets(GLenum target) {
|
|||
break;
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
return faceTargets;
|
||||
return face2DTargets;
|
||||
}
|
||||
|
||||
GLTexture::GLTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture, GLuint id) :
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
if (gltexture) {
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
} else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0);
|
||||
} else {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0,
|
||||
b._subresource);
|
||||
|
@ -98,6 +100,8 @@ public:
|
|||
if (gltexture) {
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
} else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0);
|
||||
} else {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0,
|
||||
_gpuObject.getDepthStencilBufferSubresource());
|
||||
|
|
|
@ -216,19 +216,29 @@ void GL41FixedAllocationTexture::allocateStorage() const {
|
|||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||
const auto numMips = _gpuObject.getNumMips();
|
||||
const auto numSlices = _gpuObject.getNumSlices();
|
||||
const auto numSamples = _gpuObject.getNumSamples();
|
||||
|
||||
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
for (GLint level = 0; level < numMips; level++) {
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||
for (GLenum target : getFaceTargets(_target)) {
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||
texelFormat.type, nullptr);
|
||||
} else {
|
||||
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||
texelFormat.format, texelFormat.type, nullptr);
|
||||
if (!_gpuObject.isMultisample()) {
|
||||
for (GLint level = 0; level < numMips; level++) {
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||
for (GLenum target : getFaceTargets(_target)) {
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||
texelFormat.type, nullptr);
|
||||
} else {
|
||||
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||
texelFormat.format, texelFormat.type, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto dimensions = _gpuObject.getDimensions();
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, GL_FALSE);
|
||||
} else {
|
||||
glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, dimensions.z, GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
if (gltexture) {
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
||||
} else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
||||
} else {
|
||||
glNamedFramebufferTextureLayer(_id, colorAttachments[unit], gltexture->_texture, 0, b._subresource);
|
||||
}
|
||||
|
@ -93,6 +95,9 @@ public:
|
|||
if (gltexture) {
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
||||
}
|
||||
else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
||||
} else {
|
||||
glNamedFramebufferTextureLayer(_id, attachement, gltexture->_texture, 0,
|
||||
_gpuObject.getDepthStencilBufferSubresource());
|
||||
|
|
|
@ -380,11 +380,22 @@ void GL45FixedAllocationTexture::allocateStorage() const {
|
|||
const auto dimensions = _gpuObject.getDimensions();
|
||||
const auto mips = _gpuObject.getNumMips();
|
||||
const auto numSlices = _gpuObject.getNumSlices();
|
||||
const auto numSamples = _gpuObject.getNumSamples();
|
||||
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
|
||||
if (!_gpuObject.isMultisample()) {
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
} else {
|
||||
glTextureStorage3D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices);
|
||||
}
|
||||
} else {
|
||||
glTextureStorage3D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices);
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTextureStorage2DMultisample(_id, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, GL_FALSE);
|
||||
}
|
||||
else {
|
||||
glTextureStorage3DMultisample(_id, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, GL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
|
|
|
@ -130,6 +130,8 @@ public:
|
|||
|
||||
}
|
||||
#endif
|
||||
} else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0);
|
||||
} else {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0,
|
||||
b._subresource);
|
||||
|
@ -162,6 +164,8 @@ public:
|
|||
if (gltexture) {
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
} else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0);
|
||||
} else {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0,
|
||||
_gpuObject.getDepthStencilBufferSubresource());
|
||||
|
|
|
@ -272,28 +272,40 @@ void GLESFixedAllocationTexture::allocateStorage() const {
|
|||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||
const auto numMips = _gpuObject.getNumMips();
|
||||
const auto numSlices = _gpuObject.getNumSlices();
|
||||
const auto numSamples = _gpuObject.getNumSamples();
|
||||
|
||||
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
for (GLint level = 0; level < numMips; level++) {
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||
for (GLenum target : getFaceTargets(_target)) {
|
||||
if (texelFormat.isCompressed()) {
|
||||
auto size = getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat);
|
||||
if (!_gpuObject.isArray()) {
|
||||
glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, size, nullptr);
|
||||
if (!_gpuObject.isMultisample()) {
|
||||
for (GLint level = 0; level < numMips; level++) {
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||
for (GLenum target : getFaceTargets(_target)) {
|
||||
if (texelFormat.isCompressed()) {
|
||||
auto size = getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat);
|
||||
if (!_gpuObject.isArray()) {
|
||||
glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, size, nullptr);
|
||||
} else {
|
||||
glCompressedTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, size * numSlices, nullptr);
|
||||
}
|
||||
} else {
|
||||
glCompressedTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, size * numSlices, nullptr);
|
||||
}
|
||||
} else {
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||
texelFormat.type, nullptr);
|
||||
} else {
|
||||
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||
texelFormat.format, texelFormat.type, nullptr);
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||
texelFormat.type, nullptr);
|
||||
} else {
|
||||
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||
texelFormat.format, texelFormat.type, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto dimensions = _gpuObject.getDimensions();
|
||||
if (!_gpuObject.isArray()) {
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples,
|
||||
texelFormat.internalFormat, dimensions.x, dimensions.y,
|
||||
GL_FALSE);
|
||||
} else {
|
||||
// NOT SUPPORTED (yet)
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
|
|
|
@ -176,10 +176,18 @@ TexturePointer Texture::createRenderBuffer(const Element& texelFormat, uint16 wi
|
|||
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
||||
}
|
||||
|
||||
TexturePointer Texture::createRenderBufferMultisample(const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples, const Sampler& sampler) {
|
||||
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, numSamples, 0, gpu::Texture::SINGLE_MIP, sampler);
|
||||
}
|
||||
|
||||
TexturePointer Texture::createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips, const Sampler& sampler) {
|
||||
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, numSlices, numMips, sampler);
|
||||
}
|
||||
|
||||
TexturePointer Texture::createRenderBufferMultisampleArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples, const Sampler& sampler) {
|
||||
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, numSamples, numSlices, gpu::Texture::SINGLE_MIP, sampler);
|
||||
}
|
||||
|
||||
TexturePointer Texture::create1D(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) {
|
||||
return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, numMips, sampler);
|
||||
}
|
||||
|
|
|
@ -387,7 +387,9 @@ public:
|
|||
static TexturePointer create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createRenderBufferMultisample(const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createRenderBufferMultisampleArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||
static TexturePointer createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler());
|
||||
|
||||
|
@ -435,6 +437,7 @@ public:
|
|||
uint16 getNumSamples() const { return _numSamples; }
|
||||
// NumSamples can only have certain values based on the hw
|
||||
static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
|
||||
bool isMultisample() const { return _numSamples > 1; }
|
||||
|
||||
// max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))]
|
||||
// It is defined at creation time (immutable)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class GraphicsScriptingInterface : public QObject, public QScriptable, public Dependency {
|
||||
|
|
|
@ -5,3 +5,4 @@ link_hifi_libraries(shared)
|
|||
|
||||
include_hifi_library_headers(gpu)
|
||||
include_hifi_library_headers(graphics)
|
||||
include_hifi_library_headers(image)
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <graphics/Geometry.h>
|
||||
#include <graphics/Material.h>
|
||||
|
||||
#include <image/ColorChannel.h>
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
#define HFM_PACK_NORMALS 0
|
||||
#else
|
||||
|
@ -123,6 +125,7 @@ public:
|
|||
QString name;
|
||||
QByteArray filename;
|
||||
QByteArray content;
|
||||
image::ColorChannel sourceChannel { image::ColorChannel::NONE };
|
||||
|
||||
Transform transform;
|
||||
int maxNumPixels { MAX_NUM_PIXELS_FOR_FBX_TEXTURE };
|
||||
|
|
26
libraries/image/src/image/ColorChannel.h
Normal file
26
libraries/image/src/image/ColorChannel.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// ColorChannel.h
|
||||
// libraries/image/src/image
|
||||
//
|
||||
// Created by Sabrina Shanman on 2019/02/12.
|
||||
// Copyright 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_image_ColorChannel_h
|
||||
#define hifi_image_ColorChannel_h
|
||||
|
||||
namespace image {
|
||||
enum class ColorChannel {
|
||||
NONE,
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE,
|
||||
ALPHA,
|
||||
COUNT
|
||||
};
|
||||
};
|
||||
|
||||
#endif // hifi_image_ColorChannel_h
|
|
@ -16,6 +16,7 @@
|
|||
#include <QtCore/QtGlobal>
|
||||
#include <QUrl>
|
||||
#include <QImage>
|
||||
#include <QRgb>
|
||||
#include <QBuffer>
|
||||
#include <QImageReader>
|
||||
|
||||
|
@ -221,7 +222,45 @@ QImage processRawImageData(QIODevice& content, const std::string& filename) {
|
|||
return QImage();
|
||||
}
|
||||
|
||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& filename,
|
||||
void mapToRedChannel(QImage& image, ColorChannel sourceChannel) {
|
||||
// Change format of image so we know exactly how to process it
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
for (int i = 0; i < image.height(); i++) {
|
||||
QRgb* pixel = reinterpret_cast<QRgb*>(image.scanLine(i));
|
||||
// Past end pointer
|
||||
QRgb* lineEnd = pixel + image.width();
|
||||
|
||||
// Transfer channel data from source to target
|
||||
for (; pixel < lineEnd; pixel++) {
|
||||
int colorValue;
|
||||
switch (sourceChannel) {
|
||||
case ColorChannel::RED:
|
||||
colorValue = qRed(*pixel);
|
||||
break;
|
||||
case ColorChannel::GREEN:
|
||||
colorValue = qGreen(*pixel);
|
||||
break;
|
||||
case ColorChannel::BLUE:
|
||||
colorValue = qBlue(*pixel);
|
||||
break;
|
||||
case ColorChannel::ALPHA:
|
||||
colorValue = qAlpha(*pixel);
|
||||
break;
|
||||
default:
|
||||
colorValue = qRed(*pixel);
|
||||
break;
|
||||
}
|
||||
|
||||
// Dump the color in the red channel, ignore the rest
|
||||
*pixel = qRgba(colorValue, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& filename, ColorChannel sourceChannel,
|
||||
int maxNumPixels, TextureUsage::Type textureType,
|
||||
bool compress, BackendTarget target, const std::atomic<bool>& abortProcessing) {
|
||||
|
||||
|
@ -252,6 +291,11 @@ gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::
|
|||
QSize(originalWidth, originalHeight) << " to " <<
|
||||
QSize(imageWidth, imageHeight) << ")";
|
||||
}
|
||||
|
||||
// Re-map to image with single red channel texture if requested
|
||||
if (sourceChannel != ColorChannel::NONE) {
|
||||
mapToRedChannel(image, sourceChannel);
|
||||
}
|
||||
|
||||
auto loader = TextureUsage::getTextureLoaderForType(textureType);
|
||||
auto texture = loader(std::move(image), filename, compress, target, abortProcessing);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <gpu/Texture.h>
|
||||
|
||||
#include "ColorChannel.h"
|
||||
|
||||
class QByteArray;
|
||||
class QImage;
|
||||
|
||||
|
@ -81,7 +83,7 @@ gpu::TexturePointer processCubeTextureColorFromImage(QImage&& srcImage, const st
|
|||
|
||||
const QStringList getSupportedFormats();
|
||||
|
||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url,
|
||||
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url, ColorChannel sourceChannel,
|
||||
int maxNumPixels, TextureUsage::Type textureType,
|
||||
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing = false);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "TouchscreenDevice.h"
|
||||
#include "TouchscreenVirtualPadDevice.h"
|
||||
|
||||
#if !defined(CUSTOM_INPUT_PLUGINS)
|
||||
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
||||
InputPluginList getInputPlugins() {
|
||||
InputPlugin* PLUGIN_POOL[] = {
|
||||
|
@ -37,6 +38,7 @@ InputPluginList getInputPlugins() {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void saveInputPluginSettings(const InputPluginList& plugins) {
|
||||
foreach (auto inputPlugin, plugins) {
|
||||
|
|
|
@ -471,7 +471,7 @@ graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl
|
|||
}
|
||||
|
||||
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
|
||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels, hfmTexture.sourceChannel);
|
||||
_textures[channel] = Texture { hfmTexture.name, texture };
|
||||
|
||||
auto map = std::make_shared<graphics::TextureMap>();
|
||||
|
|
|
@ -192,6 +192,7 @@ public:
|
|||
image::TextureUsage::Type type;
|
||||
const QByteArray& content;
|
||||
int maxNumPixels;
|
||||
image::ColorChannel sourceChannel;
|
||||
};
|
||||
|
||||
namespace std {
|
||||
|
@ -206,19 +207,19 @@ namespace std {
|
|||
struct hash<TextureExtra> {
|
||||
size_t operator()(const TextureExtra& textureExtra) const {
|
||||
size_t result = 0;
|
||||
hash_combine(result, (int)textureExtra.type, textureExtra.content, textureExtra.maxNumPixels);
|
||||
hash_combine(result, (int)textureExtra.type, textureExtra.content, textureExtra.maxNumPixels, (int)textureExtra.sourceChannel);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxNumPixels) {
|
||||
ScriptableResource* TextureCache::prefetch(const QUrl& url, int type, int maxNumPixels, image::ColorChannel sourceChannel) {
|
||||
auto byteArray = QByteArray();
|
||||
TextureExtra extra = { (image::TextureUsage::Type)type, byteArray, maxNumPixels };
|
||||
TextureExtra extra = { (image::TextureUsage::Type)type, byteArray, maxNumPixels, sourceChannel };
|
||||
return ResourceCache::prefetch(url, &extra, std::hash<TextureExtra>()(extra));
|
||||
}
|
||||
|
||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels) {
|
||||
NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels, image::ColorChannel sourceChannel) {
|
||||
if (url.scheme() == RESOURCE_SCHEME) {
|
||||
return getResourceTexture(url);
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, image::TextureUs
|
|||
query.addQueryItem("skybox", "");
|
||||
modifiedUrl.setQuery(query.toString());
|
||||
}
|
||||
TextureExtra extra = { type, content, maxNumPixels };
|
||||
TextureExtra extra = { type, content, maxNumPixels, sourceChannel };
|
||||
return ResourceCache::getResource(modifiedUrl, QUrl(), &extra, std::hash<TextureExtra>()(extra)).staticCast<NetworkTexture>();
|
||||
}
|
||||
|
||||
|
@ -345,6 +346,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool resourceTexture) :
|
|||
NetworkTexture::NetworkTexture(const NetworkTexture& other) :
|
||||
Resource(other),
|
||||
_type(other._type),
|
||||
_sourceChannel(other._sourceChannel),
|
||||
_currentlyLoadingResourceType(other._currentlyLoadingResourceType),
|
||||
_originalWidth(other._originalWidth),
|
||||
_originalHeight(other._originalHeight),
|
||||
|
@ -352,6 +354,11 @@ NetworkTexture::NetworkTexture(const NetworkTexture& other) :
|
|||
_height(other._height),
|
||||
_maxNumPixels(other._maxNumPixels)
|
||||
{
|
||||
if (_width == 0 || _height == 0 ||
|
||||
other._currentlyLoadingResourceType == ResourceType::META ||
|
||||
(other._currentlyLoadingResourceType == ResourceType::KTX && other._ktxResourceState != KTXResourceState::WAITING_FOR_MIP_REQUEST)) {
|
||||
_startedLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isLocalUrl(const QUrl& url) {
|
||||
|
@ -363,6 +370,7 @@ void NetworkTexture::setExtra(void* extra) {
|
|||
const TextureExtra* textureExtra = static_cast<const TextureExtra*>(extra);
|
||||
_type = textureExtra ? textureExtra->type : image::TextureUsage::DEFAULT_TEXTURE;
|
||||
_maxNumPixels = textureExtra ? textureExtra->maxNumPixels : ABSOLUTE_MAX_TEXTURE_NUM_PIXELS;
|
||||
_sourceChannel = textureExtra ? textureExtra->sourceChannel : image::ColorChannel::NONE;
|
||||
|
||||
_textureSource = std::make_shared<gpu::TextureSource>(_url, (int)_type);
|
||||
_lowestRequestedMipLevel = 0;
|
||||
|
@ -424,7 +432,8 @@ gpu::TexturePointer NetworkTexture::getFallbackTexture() const {
|
|||
class ImageReader : public QRunnable {
|
||||
public:
|
||||
ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url,
|
||||
const QByteArray& data, size_t extraHash, int maxNumPixels);
|
||||
const QByteArray& data, size_t extraHash, int maxNumPixels,
|
||||
image::ColorChannel sourceChannel);
|
||||
void run() override final;
|
||||
void read();
|
||||
|
||||
|
@ -436,6 +445,7 @@ private:
|
|||
QByteArray _content;
|
||||
size_t _extraHash;
|
||||
int _maxNumPixels;
|
||||
image::ColorChannel _sourceChannel;
|
||||
};
|
||||
|
||||
NetworkTexture::~NetworkTexture() {
|
||||
|
@ -1068,7 +1078,7 @@ void NetworkTexture::loadTextureContent(const QByteArray& content) {
|
|||
return;
|
||||
}
|
||||
|
||||
QThreadPool::globalInstance()->start(new ImageReader(_self, _url, content, _extraHash, _maxNumPixels));
|
||||
QThreadPool::globalInstance()->start(new ImageReader(_self, _url, content, _extraHash, _maxNumPixels, _sourceChannel));
|
||||
}
|
||||
|
||||
void NetworkTexture::refresh() {
|
||||
|
@ -1093,12 +1103,13 @@ void NetworkTexture::refresh() {
|
|||
Resource::refresh();
|
||||
}
|
||||
|
||||
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url, const QByteArray& data, size_t extraHash, int maxNumPixels) :
|
||||
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url, const QByteArray& data, size_t extraHash, int maxNumPixels, image::ColorChannel sourceChannel) :
|
||||
_resource(resource),
|
||||
_url(url),
|
||||
_content(data),
|
||||
_extraHash(extraHash),
|
||||
_maxNumPixels(maxNumPixels)
|
||||
_maxNumPixels(maxNumPixels),
|
||||
_sourceChannel(sourceChannel)
|
||||
{
|
||||
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||
listSupportedImageFormats();
|
||||
|
@ -1206,7 +1217,7 @@ void ImageReader::read() {
|
|||
constexpr bool shouldCompress = false;
|
||||
#endif
|
||||
auto target = getBackendTarget();
|
||||
texture = image::processImage(std::move(buffer), _url.toString().toStdString(), _maxNumPixels, networkTexture->getTextureType(), shouldCompress, target);
|
||||
texture = image::processImage(std::move(buffer), _url.toString().toStdString(), _sourceChannel, _maxNumPixels, networkTexture->getTextureType(), shouldCompress, target);
|
||||
|
||||
if (!texture) {
|
||||
QMetaObject::invokeMethod(resource.data(), "setImage",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <DependencyManager.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <graphics/TextureMap.h>
|
||||
#include <image/ColorChannel.h>
|
||||
#include <image/Image.h>
|
||||
#include <ktx/KTX.h>
|
||||
#include <TextureMeta.h>
|
||||
|
@ -96,6 +97,7 @@ private:
|
|||
friend class ImageReader;
|
||||
|
||||
image::TextureUsage::Type _type;
|
||||
image::ColorChannel _sourceChannel;
|
||||
|
||||
enum class ResourceType {
|
||||
META,
|
||||
|
@ -178,7 +180,8 @@ public:
|
|||
|
||||
/// Loads a texture from the specified URL.
|
||||
NetworkTexturePointer getTexture(const QUrl& url, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE,
|
||||
const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);
|
||||
const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS,
|
||||
image::ColorChannel sourceChannel = image::ColorChannel::NONE);
|
||||
|
||||
gpu::TexturePointer getTextureByHash(const std::string& hash);
|
||||
gpu::TexturePointer cacheTextureByHash(const std::string& hash, const gpu::TexturePointer& texture);
|
||||
|
@ -201,7 +204,7 @@ signals:
|
|||
protected:
|
||||
|
||||
// Overload ResourceCache::prefetch to allow specifying texture type for loads
|
||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS);
|
||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, image::ColorChannel sourceChannel = image::ColorChannel::NONE);
|
||||
|
||||
virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
|
||||
QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
|
||||
|
|
|
@ -30,6 +30,7 @@ class TextureCacheScriptingInterface : public ScriptableResourceCache, public De
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*/
|
||||
|
||||
class Midi : public QObject, public Dependency {
|
||||
|
|
|
@ -30,6 +30,7 @@ class ModelCacheScriptingInterface : public ScriptableResourceCache, public Depe
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} numTotal - Total number of total resources. <em>Read-only.</em>
|
||||
* @property {number} numCached - Total number of cached resource. <em>Read-only.</em>
|
||||
|
|
|
@ -43,6 +43,7 @@ const QString GET_PLACE = "/api/v1/places/%1";
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
* @property {Uuid} domainID - A UUID uniquely identifying the domain you're visiting. Is {@link Uuid|Uuid.NULL} if you're not
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*/
|
||||
|
|
|
@ -95,6 +95,7 @@ class ScriptableResource : public QObject {
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*/
|
||||
|
|
|
@ -171,6 +171,8 @@ private:
|
|||
void handleHeadPose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData,
|
||||
const ovrRigidBodyPosef& headPose);
|
||||
|
||||
void reconnectTouchControllers(ovrMobile* session);
|
||||
|
||||
// perform an action when the TouchDevice mutex is acquired.
|
||||
using Locker = std::unique_lock<std::recursive_mutex>;
|
||||
|
||||
|
@ -637,7 +639,6 @@ controller::Input::NamedVector OculusMobileInputDevice::getAvailableInputs() con
|
|||
makePair(RIGHT_THUMB_UP, "RightThumbUp"),
|
||||
makePair(LEFT_INDEX_POINT, "LeftIndexPoint"),
|
||||
makePair(RIGHT_INDEX_POINT, "RightIndexPoint"),
|
||||
|
||||
makePair(BACK, "LeftApplicationMenu"),
|
||||
makePair(START, "RightApplicationMenu"),
|
||||
};
|
||||
|
@ -665,8 +666,40 @@ OculusMobileInputDevice::OculusMobileInputDevice(ovrMobile* session, const std::
|
|||
|
||||
void OculusMobileInputDevice::updateHands(ovrMobile* session) {
|
||||
_headTracking = vrapi_GetPredictedTracking2(session, 0.0);
|
||||
|
||||
bool touchControllerNotConnected = false;
|
||||
for (auto& hand : _hands) {
|
||||
hand.update(session);
|
||||
|
||||
if (hand.stateResult < 0 || hand.trackingResult < 0) {
|
||||
touchControllerNotConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (touchControllerNotConnected) {
|
||||
reconnectTouchControllers(session);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusMobileInputDevice::reconnectTouchControllers(ovrMobile* session) {
|
||||
uint32_t deviceIndex { 0 };
|
||||
ovrInputCapabilityHeader capsHeader;
|
||||
while (vrapi_EnumerateInputDevices(session, deviceIndex, &capsHeader) >= 0) {
|
||||
if (capsHeader.Type == ovrControllerType_TrackedRemote) {
|
||||
ovrInputTrackedRemoteCapabilities caps;
|
||||
caps.Header = capsHeader;
|
||||
vrapi_GetInputDeviceCapabilities(session, &caps.Header);
|
||||
|
||||
if (caps.ControllerCapabilities & ovrControllerCaps_LeftHand || caps.ControllerCapabilities & ovrControllerCaps_RightHand) {
|
||||
size_t handIndex = caps.ControllerCapabilities & ovrControllerCaps_LeftHand ? 0 : 1;
|
||||
HandData& handData = _hands[handIndex];
|
||||
handData.state.Header.ControllerType = ovrControllerType_TrackedRemote;
|
||||
handData.valid = true;
|
||||
handData.caps = caps;
|
||||
handData.update(session);
|
||||
}
|
||||
}
|
||||
++deviceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,4 +724,4 @@ InputPluginList getInputPlugins() {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ bool OculusMobileDisplayPlugin::internalActivate() {
|
|||
|
||||
withOvrJava([&](const ovrJava* java){
|
||||
_renderTargetSize = glm::uvec2{
|
||||
vrapi_GetSystemPropertyInt(java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH),
|
||||
2 * vrapi_GetSystemPropertyInt(java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH),
|
||||
vrapi_GetSystemPropertyInt(java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT),
|
||||
};
|
||||
});
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {boolean} running - <em>Read-only.</em>
|
||||
*/
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {number} Ray Ray picks intersect a ray with the nearest object in front of them, along a given direction.
|
||||
* @property {number} Stylus Stylus picks provide "tapping" functionality on/into flat surfaces.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(TARGET_NAME procedural)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared gpu shaders networking graphics material-networking ktx image)
|
||||
|
||||
link_hifi_libraries(shared gpu shaders networking graphics material-networking ktx image)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QtQml/QtQml>
|
||||
#include <QtQml/QQmlEngine>
|
||||
#include <QtQml/QQmlComponent>
|
||||
#include <QtQml/QQmlFileSelector>
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
#include <QtQuick/QQuickRenderControl>
|
||||
|
@ -43,7 +44,21 @@ static QSize clampSize(const QSize& qsize, uint32_t maxDimension) {
|
|||
const QmlContextObjectCallback OffscreenSurface::DEFAULT_CONTEXT_OBJECT_CALLBACK = [](QQmlContext*, QQuickItem*) {};
|
||||
const QmlContextCallback OffscreenSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*) {};
|
||||
|
||||
QQmlFileSelector* OffscreenSurface::getFileSelector() {
|
||||
auto context = getSurfaceContext();
|
||||
if (!context) {
|
||||
return nullptr;
|
||||
}
|
||||
auto engine = context->engine();
|
||||
if (!engine) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return QQmlFileSelector::get(engine);
|
||||
}
|
||||
|
||||
void OffscreenSurface::initializeEngine(QQmlEngine* engine) {
|
||||
new QQmlFileSelector(engine);
|
||||
}
|
||||
|
||||
using namespace hifi::qml::impl;
|
||||
|
|
|
@ -30,6 +30,7 @@ class QQmlComponent;
|
|||
class QQuickWindow;
|
||||
class QQuickItem;
|
||||
class OffscreenQmlSharedObject;
|
||||
class QQmlFileSelector;
|
||||
|
||||
namespace hifi { namespace qml {
|
||||
|
||||
|
@ -72,6 +73,7 @@ public:
|
|||
QQuickWindow* getWindow();
|
||||
QObject* getEventHandler();
|
||||
QQmlContext* getSurfaceContext();
|
||||
QQmlFileSelector* getFileSelector();
|
||||
|
||||
// Checks to see if a new texture is available. If one is, the function returns true and
|
||||
// textureAndFence will be populated with the texture ID and a fence which will be signalled
|
||||
|
|
|
@ -79,8 +79,8 @@ void ToneMappingEffect::render(RenderArgs* args, const gpu::TexturePointer& ligh
|
|||
|
||||
|
||||
void ToneMappingDeferred::configure(const Config& config) {
|
||||
_toneMappingEffect.setExposure(config.exposure);
|
||||
_toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve);
|
||||
_toneMappingEffect.setExposure(config.exposure);
|
||||
_toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve);
|
||||
}
|
||||
|
||||
void ToneMappingDeferred::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
|
|
|
@ -37,7 +37,7 @@ int getToneCurve() {
|
|||
}
|
||||
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_TM_COLOR) uniform sampler2D colorMap;
|
||||
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*/
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue