118 GgApp(
int major = 0,
int minor = 1);
162 int main(
int argc,
const char*
const* argv);
173 GLFWwindow* window{
nullptr };
176 std::array<GLsizei, 2> size;
179 std::array<GLsizei, 2> fboSize;
181#if defined(IMGUI_VERSION)
183 GLsizei menubarHeight{ 0 };
187 GLfloat aspect{ 1.0f };
190 std::array<GLfloat, 3> velocity{ 1.0f, 1.0f, 0.1f };
193 std::array<bool, GG_BUTTON_COUNT> status{};
196 struct HumanInterface
202 std::array<std::array<int, 2>, 4> arrow{};
205 std::array<GLfloat, 2> mouse{};
208 std::array<GLfloat, 2> wheel{};
211 std::array<std::array<gg::GgVector, 2>,
GG_BUTTON_COUNT> translation{};
214 std::array<gg::GgTrackball, GG_BUTTON_COUNT> rotation;
230 void calcTranslation(
int button,
const std::array<GLfloat, 3>& velocity);
234 std::array<HumanInterface, GG_INTERFACE_COUNT> interfaceData;
237 int interfaceNo{ 0 };
242 void* userPointer{
nullptr };
243 void (*resizeFunc)(
const Window* window,
int width,
int height){
nullptr };
244 void (*keyboardFunc)(
const Window* window,
int key,
int scancode,
int action,
int mods){
nullptr };
245 void (*mouseFunc)(
const Window* window,
int button,
int action,
int mods){
nullptr };
246 void (*wheelFunc)(
const Window* window,
double x,
double y){
nullptr };
251 static void resize(GLFWwindow* window,
int width,
int height);
256 static void keyboard(GLFWwindow* window,
int key,
int scancode,
int action,
int mods);
261 static void mouse(GLFWwindow* window,
int button,
int action,
int mods);
266 static void wheel(GLFWwindow* window,
double x,
double y);
279 Window(
const std::string& title =
"GLFW Window",
int width = 640,
int height = 480,
280 int fullscreen = 0, GLFWwindow* share =
nullptr);
305 glfwDestroyWindow(window);
341 glfwSetWindowShouldClose(window, flag);
352 return glfwWindowShouldClose(window) != GLFW_FALSE;
360 explicit operator bool();
372 if (!glfwGetWindowAttrib(window, GLFW_ICONIFIED)) glViewport(0, 0, fboSize[0], fboSize[1]);
380#if defined(IMGUI_VERSION)
386 void setMenubarHeight(GLsizei height)
389 menubarHeight = height;
495#if defined(IMGUI_VERSION)
497 if (ImGui::GetIO().WantCaptureKeyboard)
return false;
500 return glfwGetKey(window, key) != GLFW_RELEASE;
510 assert(
static_cast<size_t>(no) < interfaceData.size());
523 velocity = std::array<GLfloat, 3>{ vx, vy, vz };
533 auto& current_if{ interfaceData[interfaceNo] };
534 const int key{ current_if.lastKey };
535 current_if.lastKey = 0;
546 auto getArrow(
int direction = 0,
int mods = 0)
const
548 const auto& current_if{ interfaceData[interfaceNo] };
549 return static_cast<GLfloat
>(current_if.arrow[mods & 3][direction & 1]);
686 const auto& current_if{ interfaceData[interfaceNo] };
687 return current_if.mouse.data();
697 const auto& current_if{ interfaceData[interfaceNo] };
698 position[0] = current_if.mouse[0];
699 position[1] = current_if.mouse[1];
710 const auto& current_if{ interfaceData[interfaceNo] };
711 return current_if.mouse[direction & 1];
721 const auto& current_if{ interfaceData[interfaceNo] };
722 return current_if.mouse[0];
732 const auto& current_if{ interfaceData[interfaceNo] };
733 return current_if.mouse[1];
743 const auto& current_if{ interfaceData[interfaceNo] };
744 return current_if.wheel.data();
754 const auto& current_if{ interfaceData[interfaceNo] };
755 rotation[0] = current_if.wheel[0];
756 rotation[1] = current_if.wheel[1];
767 const auto& current_if{ interfaceData[interfaceNo] };
768 return current_if.wheel[direction & 1];
778 const auto& current_if{ interfaceData[interfaceNo] };
779 return current_if.wheel[0];
789 const auto& current_if{ interfaceData[interfaceNo] };
790 return current_if.wheel[1];
801 const auto& current_if{ interfaceData[interfaceNo] };
802 assert(button >= GLFW_MOUSE_BUTTON_1 && button < GLFW_MOUSE_BUTTON_1 +
GG_BUTTON_COUNT);
803 return current_if.translation[button][1];
814 const auto& current_if{ interfaceData[interfaceNo] };
815 assert(button >= GLFW_MOUSE_BUTTON_1 && button < GLFW_MOUSE_BUTTON_1 +
GG_BUTTON_COUNT);
816 const auto& t{ current_if.translation[button][1] };
820 1.0f, 0.0f, 0.0f, 0.0f,
821 0.0f, 1.0f, 0.0f, 0.0f,
822 0.0f, 0.0f, 1.0f, 0.0f,
823 t[0], t[1], t[2], 1.0f
837 const auto& current_if{ interfaceData[interfaceNo] };
838 assert(button >= GLFW_MOUSE_BUTTON_1 && button < GLFW_MOUSE_BUTTON_1 +
GG_BUTTON_COUNT);
839 const auto& t{ current_if.translation[button][1] };
843 t[2] + 1.0f, 0.0f, 0.0f, 0.0f,
844 0.0f, t[2] + 1.0f, 0.0f, 0.0f,
845 0.0f, 0.0f, 1.0f, 0.0f,
846 t[0], t[1], 0.0f, 1.0f
860 const auto& current_if{ interfaceData[interfaceNo] };
861 assert(button >= GLFW_MOUSE_BUTTON_1 && button < GLFW_MOUSE_BUTTON_1 +
GG_BUTTON_COUNT);
862 return current_if.rotation[button].getQuaternion();
873 const auto& current_if{ interfaceData[interfaceNo] };
874 assert(button >= GLFW_MOUSE_BUTTON_1 && button < GLFW_MOUSE_BUTTON_1 +
GG_BUTTON_COUNT);
875 return current_if.rotation[button].getMatrix();
884 for (
auto& tb : interfaceData[interfaceNo].rotation) tb.reset();
893 interfaceData[interfaceNo].resetTranslation();
925 userPointer = pointer;
969#if defined(GG_USE_OPENXR)
995 XrInstance instance{ XR_NULL_HANDLE };
996 XrSystemId systemId{ XR_NULL_SYSTEM_ID };
999 std::string systemName;
1002 XrSession session{ XR_NULL_HANDLE };
1003 XrSessionState sessionState{ XR_SESSION_STATE_UNKNOWN };
1006 XrSpace appSpace{ XR_NULL_HANDLE };
1007 XrReferenceSpaceType referenceSpaceType{ XR_REFERENCE_SPACE_TYPE_STAGE };
1010 std::vector<XrViewConfigurationView> views;
1011 std::vector<XrView> viewStates;
1014 std::vector<XrSwapchain> swapchains;
1015 std::vector<std::vector<XrSwapchainImageOpenGLKHR>> swapchainImages;
1018 std::vector<GLuint> openxrFbo;
1019 std::vector<GLuint> openxrDepth;
1022 bool swapchainIsSrgb{
true };
1025 XrEnvironmentBlendMode blendMode{ XR_ENVIRONMENT_BLEND_MODE_OPAQUE };
1028 XrFrameState frameState{ XR_TYPE_FRAME_STATE };
1029 bool isSessionRunning{
false };
1032 bool frameBegun{
false };
1035 bool viewPoseValid{
false };
1038 bool initialized{
false };
1041 std::vector<uint32_t> currentImageIndex;
1044 std::vector<bool> imageAcquired;
1047 int mirrorView{ 0 };
1050 const Window* window{
nullptr };
1053 XrActionSet actionSet{ XR_NULL_HANDLE };
1056 XrAction aimPoseAction{ XR_NULL_HANDLE };
1057 XrAction gripPoseAction{ XR_NULL_HANDLE };
1058 XrAction triggerAction{ XR_NULL_HANDLE };
1059 XrAction gripAction{ XR_NULL_HANDLE };
1060 XrAction thumbstickAction{ XR_NULL_HANDLE };
1061 XrAction thumbstickClickAction{ XR_NULL_HANDLE };
1062 XrAction primaryButtonAction{ XR_NULL_HANDLE };
1063 XrAction secondaryButtonAction{ XR_NULL_HANDLE };
1064 XrAction menuButtonAction{ XR_NULL_HANDLE };
1065 XrAction hapticAction{ XR_NULL_HANDLE };
1068 XrSpace aimSpace[Hand::Count]{ XR_NULL_HANDLE, XR_NULL_HANDLE };
1069 XrSpace gripSpace[Hand::Count]{ XR_NULL_HANDLE, XR_NULL_HANDLE };
1072 struct ControllerState
1074 bool isTracked{
false };
1075 XrPosef gripPose{ { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f } };
1076 XrPosef aimPose{ { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f } };
1077 float trigger{ 0.0f };
1079 std::array<float, 2> thumbstick{ 0.0f, 0.0f };
1080 bool thumbstickClick{
false };
1081 bool primaryButton{
false };
1082 bool secondaryButton{
false };
1083 bool menuButton{
false };
1085 ControllerState controllerStates[Hand::Count];
1088 XrPath handSubactionPath[Hand::Count]{ XR_NULL_PATH, XR_NULL_PATH };
1108 void createSwapchains();
1123 void blitMirror()
const;
1138 OpenXR(
const OpenXR&) =
delete;
1139 OpenXR& operator=(
const OpenXR&) =
delete;
1140 OpenXR(OpenXR&&) =
delete;
1141 OpenXR& operator=(OpenXR&&) =
delete;
1156 static OpenXR& initialize(
const Window& window,
1157 XrReferenceSpaceType spaceType = XR_REFERENCE_SPACE_TYPE_STAGE,
1158 const char* appName =
"GgApp");
1188 void select(
int eye);
1198 void select(
int eye, GLfloat* screen, GLfloat* position, GLfloat* orientation);
1209 void commit(
int eye);
1222 bool submit(
bool mirror =
true);
1229 void setMirror(
int eye);
1236 int getMirror()
const;
1243 bool isRunning()
const;
1250 bool isFocused()
const;
1257 const std::string& getSystemName()
const;
1267 gg::GgMatrix getProjectionMatrix(
int eye, GLfloat zNear = 0.1f, GLfloat zFar = 100.0f)
const;
1275 gg::GgMatrix getViewMatrix(
int eye)
const;
1283 gg::GgMatrix getPoseMatrix(
int eye)
const;
1291 gg::GgVector getPosition(
int eye)
const;
1299 gg::GgQuaternion getOrientation(
int eye)
const;
1307 const XrFovf& getFov(
int eye)
const;
1315 const XrPosef& getPose(
int eye)
const;
1322 bool isPoseValid()
const;
1330 GLsizei getWidth(
int eye = 0)
const;
1338 GLsizei getHeight(
int eye = 0)
const;
1346 GLfloat getAspect(
int eye = 0)
const;
1353 uint32_t getViewCount()
const;
1360 XrReferenceSpaceType getReferenceSpaceType()
const;
1368 bool isTracked(
int hand)
const;
1376 gg::GgMatrix getGripMatrix(
int hand)
const;
1384 gg::GgMatrix getAimMatrix(
int hand)
const;
1392 gg::GgVector getGripPosition(
int hand)
const;
1400 gg::GgQuaternion getGripOrientation(
int hand)
const;
1408 gg::GgVector getAimPosition(
int hand)
const;
1416 gg::GgQuaternion getAimOrientation(
int hand)
const;
1424 float getTrigger(
int hand)
const;
1432 float getGrip(
int hand)
const;
1440 std::array<float, 2> getThumbstick(
int hand)
const;
1448 bool getThumbstickClick(
int hand)
const;
1456 bool getPrimaryButton(
int hand)
const;
1464 bool getSecondaryButton(
int hand)
const;
1477 bool getMenuButton(
int hand = Hand::Left)
const;
1487 void applyHapticVibration(
int hand,
float durationSeconds = 0.1f,
float frequency = XR_FREQUENCY_UNSPECIFIED,
float amplitude = 0.5f);