فهرست منبع

Merge pull request #88 from jsarrett/openglexample_modernized

Openglexample modernized (SDL2, Universal Shader, CMake fixes)
TheOnlyJoey 8 سال پیش
والد
کامیت
2381fcd19c
7فایلهای تغییر یافته به همراه131 افزوده شده و 36 حذف شده
  1. 1 1
      CMakeLists.txt
  2. 1 1
      configure.ac
  3. 2 2
      examples/opengl/CMakeLists.txt
  4. 2 2
      examples/opengl/Makefile.am
  5. 21 8
      examples/opengl/gl.c
  6. 3 1
      examples/opengl/gl.h
  7. 101 21
      examples/opengl/main.c

+ 1 - 1
CMakeLists.txt

@@ -106,7 +106,7 @@ if (OPENHMD_EXAMPLE_SIMPLE)
 endif(OPENHMD_EXAMPLE_SIMPLE)
 
 if (OPENHMD_EXAMPLE_SDL)
-	find_package(SDL REQUIRED)
+	find_package(SDL2 REQUIRED)
 	find_package(GLEW REQUIRED)
 	find_package(OpenGL REQUIRED)
 	add_subdirectory(./examples/opengl)

+ 1 - 1
configure.ac

@@ -112,7 +112,7 @@ AM_CONDITIONAL([BUILD_OPENGL_EXAMPLE], [test "x$openglexample_enabled" != "xno"]
 
 # Libs required by OpenGL test
 AS_IF([test "x$openglexample_enabled" != "xno"], [
-	PKG_CHECK_MODULES([sdl], [sdl])
+	PKG_CHECK_MODULES([sdl2], [sdl2])
 
 	# Try to find OpenGL with pkg-config
 	PKG_CHECK_MODULES([GL], [gl], [],

+ 2 - 2
examples/opengl/CMakeLists.txt

@@ -1,5 +1,5 @@
 project (openglexample)
-include_directories(${CMAKE_BINARY_DIR}/include ${SDL_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR})
+include_directories(${CMAKE_BINARY_DIR}/include ${SDL2_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR})
 link_directories(${CMAKE_BINARY_DIR})
 add_executable(openglexample gl.c main.c)
-target_link_libraries(openglexample PRIVATE openhmd-shared m ${SDL_LIBRARY} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES})
+target_link_libraries(openglexample PRIVATE openhmd-shared m ${SDL2_LIBRARY} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES})

+ 2 - 2
examples/opengl/Makefile.am

@@ -1,5 +1,5 @@
 bin_PROGRAMS = openglexample
-AM_CPPFLAGS = -Wall -Werror -I$(top_srcdir)/include -DOHMD_STATIC $(sdl_CFLAGS) $(GLEW_CFLAGS)
+AM_CPPFLAGS = -Wall -Werror -I$(top_srcdir)/include -DOHMD_STATIC $(sdl2_CFLAGS) $(GLEW_CFLAGS)
 openglexample_SOURCES = gl.c main.c
 openglexample_LDADD = $(top_builddir)/src/libopenhmd.la -lm
-openglexample_LDFLAGS = -static-libtool-libs $(sdl_LIBS) $(GLEW_LIBS) $(GL_LIBS)
+openglexample_LDFLAGS = -static-libtool-libs $(sdl2_LIBS) $(GLEW_LIBS) $(GL_LIBS)

+ 21 - 8
examples/opengl/gl.c

@@ -31,18 +31,31 @@ void init_gl(gl_ctx* ctx, int w, int h)
 	}
 
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
 
-	ctx->screen = SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_GL_DOUBLEBUFFER);
-	if(ctx->screen == NULL){
-		printf("SDL_SetVideoMode failed\n");
+	ctx->window = SDL_CreateWindow("OpenHMD opengl example",
+			SDL_WINDOWPOS_UNDEFINED,
+			SDL_WINDOWPOS_UNDEFINED,
+			w, h, SDL_WINDOW_OPENGL );
+	if(ctx->window == NULL) {
+		printf("SDL_CreateWindow failed\n");
 		exit(-1);
 	}
+	ctx->w = w;
+	ctx->h = h;
+	ctx->is_fullscreen = 0;
+
+	ctx->glcontext = SDL_GL_CreateContext(ctx->window);
+	if(ctx->glcontext == NULL){
+		printf("SDL_GL_CreateContext\n");
+		exit(-1);
+	}
+
+	SDL_GL_SetSwapInterval(1);
 
 	// Disable ctrl-c catching on linux (and OS X?) 
-	#ifdef __unix
+#ifdef __unix
 	signal(SIGINT, SIG_DFL);
-	#endif
+#endif
 
 	// Load extensions.
 	glewInit();
@@ -69,7 +82,7 @@ void init_gl(gl_ctx* ctx, int w, int h)
 	glEnable(GL_POLYGON_SMOOTH); 
 	glLoadIdentity();
 
-	glViewport(0, 0, ctx->screen->w, ctx->screen->h);
+	glViewport(0, 0, ctx->w, ctx->h);
 }
 
 void ortho(gl_ctx* ctx)
@@ -78,7 +91,7 @@ void ortho(gl_ctx* ctx)
 	//glPushMatrix();
 	glLoadIdentity();
 
-	glOrtho(0.0f, ctx->screen->w, ctx->screen->h, 0.0f, -1.0f, 1.0f);
+	glOrtho(0.0f, ctx->w, ctx->h, 0.0f, -1.0f, 1.0f);
 	glMatrixMode(GL_MODELVIEW);
 	//glPushMatrix();
 	glLoadIdentity();

+ 3 - 1
examples/opengl/gl.h

@@ -17,7 +17,9 @@
 
 typedef struct {
 	int w, h;
-	SDL_Surface* screen;
+	SDL_Window* window;
+	SDL_GLContext glcontext;
+	int is_fullscreen;
 } gl_ctx;
 
 void ortho(gl_ctx* ctx);

+ 101 - 21
examples/opengl/main.c

@@ -13,15 +13,8 @@
 #include <math.h>
 #include "gl.h"
 
-/* DK1 */
-//#define TEST_WIDTH 1280
-//#define TEST_HEIGHT 800
-/* DK2 */
-#define TEST_WIDTH 1920
-#define TEST_HEIGHT 1080
 
-#define EYE_WIDTH (TEST_WIDTH / 2 * 2)
-#define EYE_HEIGHT (TEST_HEIGHT * 2)
+#define OVERSAMPLE_SCALE 2.0
 
 char* read_file(const char* filename)
 {
@@ -79,6 +72,27 @@ GLuint gen_cubes()
 	return list;
 }
 
+void draw_crosshairs(float len, float cx, float cy)
+{
+	glMatrixMode(GL_MODELVIEW);
+	glPushMatrix();
+	glLoadIdentity();
+	glMatrixMode(GL_PROJECTION);
+	glPushMatrix();
+	glLoadIdentity();
+	glBegin(GL_LINES);
+	float l = len/2.0f;
+	glVertex3f(cx - l, cy, 0.0);
+	glVertex3f(cx + l, cy, 0.0);
+	glVertex3f(cx, cy - l, 0.0);
+	glVertex3f(cx, cy + l, 0.0);
+	glEnd();
+	glMatrixMode(GL_PROJECTION);
+	glPopMatrix();
+	glMatrixMode(GL_MODELVIEW);
+	glPopMatrix();
+}
+
 void draw_scene(GLuint list)
 {
 	// draw cubes
@@ -99,6 +113,8 @@ print_matrix(float m[])
 
 int main(int argc, char** argv)
 {
+	int hmd_w, hmd_h;
+
 	ohmd_context* ctx = ohmd_ctx_create();
 	int num_devices = ohmd_ctx_probe(ctx);
 	if(num_devices < 0){
@@ -115,6 +131,10 @@ int main(int argc, char** argv)
 	ohmd_device_settings_seti(settings, OHMD_IDS_AUTOMATIC_UPDATE, &auto_update);
 
 	ohmd_device* hmd = ohmd_list_open_device_s(ctx, 0, settings);
+	ohmd_device_geti(hmd, OHMD_SCREEN_HORIZONTAL_RESOLUTION, &hmd_w);
+	ohmd_device_geti(hmd, OHMD_SCREEN_VERTICAL_RESOLUTION, &hmd_h);
+	float ipd;
+	ohmd_device_getf(hmd, OHMD_EYE_IPD, &ipd);
 	float viewport_scale[2];
 	float distortion_coeffs[4];
 	float aberr_scale[3];
@@ -136,6 +156,7 @@ int main(int argc, char** argv)
 	right_lens_center[0] = sep/2.0f;
 	//asume calibration was for lens view to which ever edge of screen is further away from lens center
 	float warp_scale = (left_lens_center[0] > right_lens_center[0]) ? left_lens_center[0] : right_lens_center[0];
+	float warp_adj = 1.0f;
 
 	ohmd_device_settings_destroy(settings);
 
@@ -145,7 +166,7 @@ int main(int argc, char** argv)
 	}
 
 	gl_ctx gl;
-	init_gl(&gl, TEST_WIDTH, TEST_HEIGHT);
+	init_gl(&gl, hmd_w, hmd_h);
 
 	SDL_ShowCursor(SDL_DISABLE);
 
@@ -158,21 +179,22 @@ int main(int argc, char** argv)
 	glUseProgram(shader);
 	glUniform1i(glGetUniformLocation(shader, "warpTexture"), 0);
 	glUniform2fv(glGetUniformLocation(shader, "ViewportScale"), 1, viewport_scale);
-	glUniform1f(glGetUniformLocation(shader, "WarpScale"), warp_scale);
-	glUniform4fv(glGetUniformLocation(shader, "HmdWarpParam"), 1, distortion_coeffs);
 	glUniform3fv(glGetUniformLocation(shader, "aberr"), 1, aberr_scale);
 	glUseProgram(0);
 
 	GLuint list = gen_cubes();
 
+	int eye_w = hmd_w/2*OVERSAMPLE_SCALE;
+	int eye_h = hmd_h*OVERSAMPLE_SCALE;
 	GLuint left_color_tex = 0, left_depth_tex = 0, left_fbo = 0;
-	create_fbo(EYE_WIDTH, EYE_HEIGHT, &left_fbo, &left_color_tex, &left_depth_tex);
+	create_fbo(eye_w, eye_h, &left_fbo, &left_color_tex, &left_depth_tex);
 
 	GLuint right_color_tex = 0, right_depth_tex = 0, right_fbo = 0;
-	create_fbo(EYE_WIDTH, EYE_HEIGHT, &right_fbo, &right_color_tex, &right_depth_tex);
+	create_fbo(eye_w, eye_h, &right_fbo, &right_color_tex, &right_depth_tex);
 
 
 	bool done = false;
+	bool crosshair_overlay = false;
 	while(!done){
 		ohmd_ctx_update(ctx);
 
@@ -184,7 +206,10 @@ int main(int argc, char** argv)
 					done = true;
 					break;
 				case SDLK_F1:
-					SDL_WM_ToggleFullScreen(gl.screen);
+					{
+						gl.is_fullscreen = !gl.is_fullscreen;
+						SDL_SetWindowFullscreen(gl.window, gl.is_fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
+					}
 					break;
 				case SDLK_F2:
 					{
@@ -210,13 +235,56 @@ int main(int argc, char** argv)
 						print_matrix(mat);
 						printf("\n");
 						printf("viewport_scale: [%0.4f, %0.4f]\n", viewport_scale[0], viewport_scale[1]);
+						printf("lens separation: %04f\n", sep);
+						printf("IPD: %0.4f\n", ipd);
 						printf("warp_scale: %0.4f\r\n", warp_scale);
 						printf("distoriton coeffs: [%0.4f, %0.4f, %0.4f, %0.4f]\n", distortion_coeffs[0], distortion_coeffs[1], distortion_coeffs[2], distortion_coeffs[3]);
 						printf("aberration coeffs: [%0.4f, %0.4f, %0.4f]\n", aberr_scale[0], aberr_scale[1], aberr_scale[2]);
 						printf("left_lens_center: [%0.4f, %0.4f]\n", left_lens_center[0], left_lens_center[1]);
-						printf("right_lens_center: [%0.4f, %0.4f]\n", left_lens_center[0], left_lens_center[1]);
+						printf("right_lens_center: [%0.4f, %0.4f]\n", right_lens_center[0], right_lens_center[1]);
 					}
 					break;
+				case SDLK_w:
+					sep += 0.001;
+					left_lens_center[0] = viewport_scale[0] - sep/2.0f;
+					right_lens_center[0] = sep/2.0f;
+					break;
+				case SDLK_q:
+					sep -= 0.001;
+					left_lens_center[0] = viewport_scale[0] - sep/2.0f;
+					right_lens_center[0] = sep/2.0f;
+					break;
+				case SDLK_a:
+					warp_adj *= 1.0/0.9;
+					break;
+				case SDLK_z:
+					warp_adj *= 0.9;
+					break;
+				case SDLK_i:
+					ipd -= 0.001;
+					ohmd_device_setf(hmd, OHMD_EYE_IPD, &ipd);
+					break;
+				case SDLK_o:
+					ipd += 0.001;
+					ohmd_device_setf(hmd, OHMD_EYE_IPD, &ipd);
+					break;
+				case SDLK_d:
+					/* toggle between distorted and undistorted views */
+					if ((distortion_coeffs[0] != 0.0) ||
+							(distortion_coeffs[1] != 0.0) ||
+							(distortion_coeffs[2] != 0.0) ||
+							(distortion_coeffs[3] != 1.0)) {
+						distortion_coeffs[0] = 0.0;
+						distortion_coeffs[1] = 0.0;
+						distortion_coeffs[2] = 0.0;
+						distortion_coeffs[3] = 1.0;
+					} else {
+						ohmd_device_getf(hmd, OHMD_UNIVERSAL_DISTORTION_K, &(distortion_coeffs[0]));
+					}
+					break;
+				case SDLK_x:
+					crosshair_overlay = ! crosshair_overlay;
+					break;
 				default:
 					break;
 				}
@@ -239,12 +307,16 @@ int main(int argc, char** argv)
 
 		// Draw scene into framebuffer.
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, left_fbo);
-		glViewport(0, 0, EYE_WIDTH, EYE_HEIGHT);
+		glViewport(0, 0, eye_w, eye_h);
 		glClearColor(0.0, 0.0, 0.0, 1.0);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 		draw_scene(list);
-		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
+		if (crosshair_overlay) {
+			glClear(GL_DEPTH_BUFFER_BIT);
+			glLineWidth(2.0*OVERSAMPLE_SCALE);
+			glColor4f(1.0, 0.5, 0.0, 1.0);
+			draw_crosshairs(0.1, 2*left_lens_center[0]/viewport_scale[0] - 1.0f, 2*left_lens_center[1]/viewport_scale[1] - 1.0f);
+		}
 
 		// set hmd rotation, for right eye.
 		glMatrixMode(GL_PROJECTION);
@@ -257,9 +329,15 @@ int main(int argc, char** argv)
 
 		// Draw scene into framebuffer.
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, right_fbo);
-		glViewport(0, 0, EYE_WIDTH, EYE_HEIGHT);
+		glViewport(0, 0, eye_w, eye_h);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 		draw_scene(list);
+		if (crosshair_overlay) {
+			glClear(GL_DEPTH_BUFFER_BIT);
+			glLineWidth(5.0);
+			glColor4f(1.0, 0.5, 0.0, 1.0);
+			draw_crosshairs(0.1, 2*right_lens_center[0]/viewport_scale[0] - 1.0f, 2*right_lens_center[1]/viewport_scale[1] - 1.0f);
+		}
 
 		// Clean up common draw state
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@@ -269,7 +347,9 @@ int main(int argc, char** argv)
 
 		// Setup ortho state.
 		glUseProgram(shader);
-		glViewport(0, 0, TEST_WIDTH, TEST_HEIGHT);
+		glUniform1f(glGetUniformLocation(shader, "WarpScale"), warp_scale*warp_adj);
+		glUniform4fv(glGetUniformLocation(shader, "HmdWarpParam"), 1, distortion_coeffs);
+		glViewport(0, 0, hmd_w, hmd_h);
 		glEnable(GL_TEXTURE_2D);
 		glColor4d(1, 1, 1, 1);
 
@@ -313,7 +393,7 @@ int main(int argc, char** argv)
 		glUseProgram(0);
 
 		// Da swap-dawup!
-		SDL_GL_SwapBuffers();
+		SDL_GL_SwapWindow(gl.window);
 		SDL_Delay(10);
 	}