aboutsummaryrefslogtreecommitdiff
path: root/include/main_application.h
blob: 3cc709170dadcb157df0d5cec7d7b73b08f02e7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <openvr.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#include <GL/glxext.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xfixes.h>

#include <stdio.h>
#include <string>
#include <cstdlib>
#include <vector>

#include <unistd.h>
#include <signal.h>
#include <libgen.h>

#include <iostream>
#include <fstream>
#include <sstream>

#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<float> &vertdata, std::vector<GLushort> &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;
};