#include #include #include #include #define GLX_GLXEXT_PROTOTYPES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "window_texture.h" class CMainApplication { public: CMainApplication( int argc, char *argv[] ); virtual ~CMainApplication(); bool BInit(); bool BInitGL(); bool BInitCompositor(); void Shutdown(); void RunMainLoop(); bool HandleInput(); void zoom_in(); void zoom_out(); void ProcessVREvent( const vr::VREvent_t & event ); void RenderFrame(); void ResetRotation(); void MoveCursor(float x, float y); void MouseButton(int button, bool down); void SetupScene(); void CreateProjectionSurface(const glm::mat4 &mat, std::vector &vertdata, std::vector &indices); bool SetupStereoRenderTargets(); void SetupCompanionWindow(); void SetupCameras(); void RenderStereoTargets(); void RenderCompanionWindow(); void RenderScene( vr::Hmd_Eye nEye ); glm::mat4 GetHMDMatrixProjectionEye( vr::Hmd_Eye nEye ); glm::mat4 GetHMDMatrixPoseEye( vr::Hmd_Eye nEye ); glm::mat4 GetCurrentViewProjectionMatrix( vr::Hmd_Eye nEye ); void UpdateHMDMatrixPose(); glm::mat4 ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose ); GLuint CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader ); bool CreateAllShaders(); bool SetCursorFromX11CursorImage(XFixesCursorImage *x11_cursor_image); // Get focused window or None Window get_focused_window(); private: bool m_bDebugOpenGL; bool m_bVerbose; bool m_bPerf; bool m_bVblank; bool m_bGlFinishHack; vr::IVRSystem *m_pHMD; vr::TrackedDevicePose_t m_rTrackedDevicePose[ vr::k_unMaxTrackedDeviceCount ]; glm::mat4 m_rmat4DevicePose[ vr::k_unMaxTrackedDeviceCount ]; // SDL bookkeeping SDL_Window *m_pCompanionWindow; uint32_t m_nCompanionWindowWidth; uint32_t m_nCompanionWindowHeight; SDL_GLContext m_pContext; // OpenGL bookkeeping int m_iTrackedControllerCount; int m_iTrackedControllerCount_Last; int m_iValidPoseCount; int m_iValidPoseCount_Last; bool m_bResetRotation; glm::vec2 m_vAnalogValue; std::string m_strPoseClasses; // what classes we saw poses for this frame char m_rDevClassChar[ vr::k_unMaxTrackedDeviceCount ]; // for each device, a character representing its class int m_iSceneVolumeWidth; int m_iSceneVolumeHeight; int m_iSceneVolumeDepth; float m_fScaleSpacing; float m_fScale; int m_iSceneVolumeInit; // if you want something other than the default 20x20x20 float m_fNearClip; float m_fFarClip; unsigned int m_uiVertcount; GLushort m_nbIndices; GLuint m_glSceneVertBuffer; GLuint m_glSceneIndexBuffer; GLuint m_unSceneVAO; GLuint m_unCompanionWindowVAO; GLuint m_glCompanionWindowIDVertBuffer; GLuint m_glCompanionWindowIDIndexBuffer; unsigned int m_uiCompanionWindowIndexSize; GLuint m_glControllerVertBuffer; GLuint m_unControllerVAO; unsigned int m_uiControllerVertcount; glm::mat4 m_mat4HMDPose; glm::mat4 m_mat4eyePosLeft; glm::mat4 m_mat4eyePosRight; glm::mat4 m_mat4ProjectionCenter; glm::mat4 m_mat4ProjectionLeft; glm::mat4 m_mat4ProjectionRight; glm::vec3 current_pos = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 hmd_pos = glm::vec3(0.0f, 0.0f, 0.0f); glm::quat hmd_rot = glm::quat(0.0f, 0.0f, 0.0f, 1.0f); glm::quat m_reset_rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f); struct VertexDataScene { glm::vec3 position; glm::vec2 texCoord; }; struct VertexDataWindow { glm::vec2 position; glm::vec2 texCoord; VertexDataWindow( const glm::vec2 & pos, const glm::vec2 tex ) : position(pos), texCoord(tex) { } }; GLuint m_unSceneProgramID; GLuint m_unCompanionWindowProgramID; GLint m_nSceneMatrixLocation; GLint m_nSceneTextureOffsetXLocation; GLint m_nSceneTextureScaleXLocation; GLint m_nCursorLocation; GLint m_nArrowSizeLocation = -1; GLint m_myTextureLocation = -1; GLint m_arrowTextureLocation = -1; struct FramebufferDesc { GLuint m_nDepthBufferId; GLuint m_nRenderTextureId; GLuint m_nRenderFramebufferId; GLuint m_nResolveTextureId; GLuint m_nResolveFramebufferId; }; FramebufferDesc leftEyeDesc; FramebufferDesc rightEyeDesc; bool CreateFrameBuffer( int nWidth, int nHeight, FramebufferDesc &framebufferDesc ); uint32_t m_nRenderWidth; uint32_t m_nRenderHeight; vr::VRActionHandle_t m_actionHideCubes = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_actionHideThisController = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_actionTriggerHaptic = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_actionAnalongInput = vr::k_ulInvalidActionHandle; vr::VRActionSetHandle_t m_actionsetDemo = vr::k_ulInvalidActionSetHandle; // X compositor Display *x_display = nullptr; Atom net_active_window_atom; Window src_window_id = None; WindowTexture window_texture; bool follow_focused = false; bool focused_window_changed = true; bool focused_window_set = false; int mouse_x; int mouse_y; int window_width; int window_height; Uint32 window_resize_time; bool window_resized = false; bool zoom_resize = false; int x_fixes_event_base; int x_fixes_error_base; GLint pixmap_texture_width = 0; GLint pixmap_texture_height = 0; enum class ViewMode { LEFT_RIGHT, RIGHT_LEFT, PLANE, SPHERE360, SPHERE360N }; enum class ProjectionMode { SPHERE, FLAT, CYLINDER, /* aka plane */ SPHERE360, SPHERE360N }; ProjectionMode projection_mode = ProjectionMode::SPHERE; double zoom = 0.0; float cursor_scale = 2.0f; ViewMode view_mode = ViewMode::LEFT_RIGHT; bool stretch = true; bool cursor_wrap = true; bool free_camera = false; bool reduce_flicker = false; double reduce_flicker_counter = 0.0; GLuint arrow_image_texture_id = 0; int arrow_image_width = 1; int arrow_image_height = 1; int cursor_offset_x = 0; int cursor_offset_y = 0; float cursor_scale_uniform[2]; double arrow_ratio; bool cursor_image_set = false; };