add openglexample from OpenHMD
This commit is contained in:
13
examples/opengl/CMakeLists.txt
Normal file
13
examples/opengl/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
project (openglexample C)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(openhmd REQUIRED)
|
||||
|
||||
add_executable(openglexample gl.c gl.h main.c)
|
||||
|
||||
target_include_directories(openglexample PRIVATE ${OPENGL_INCLUDE_DIRS})
|
||||
target_link_libraries(openglexample PRIVATE ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(openglexample PRIVATE m)
|
||||
target_link_libraries(openglexample PRIVATE openhmd)
|
||||
target_link_libraries(openglexample PRIVATE lvrc)
|
||||
|
||||
261
examples/opengl/gl.c
Normal file
261
examples/opengl/gl.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* OpenHMD - Free and Open Source API and drivers for immersive technology.
|
||||
* Copyright (C) 2013 Fredrik Hultin.
|
||||
* Copyright (C) 2013 Jakob Bornecrantz.
|
||||
* Distributed under the Boost 1.0 licence, see LICENSE for full text.
|
||||
*/
|
||||
|
||||
/* OpenGL Test - GL Helper Functions Implementation */
|
||||
|
||||
#include "gl.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <lvrc.h>
|
||||
|
||||
#ifdef __unix
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265359
|
||||
#endif
|
||||
|
||||
|
||||
void init_gl(gl_ctx* ctx, struct lvrcInstance * compositor)
|
||||
{
|
||||
memset(ctx, 0, sizeof(gl_ctx));
|
||||
|
||||
bool bSwapChainCreated = lvrcInitSwapChain(compositor);
|
||||
|
||||
if (!bSwapChainCreated)
|
||||
{
|
||||
fprintf(stderr, "swap chain not created\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static const EGLint attribs[] =
|
||||
{
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
//EGL_ALPHA_SIZE, 8,
|
||||
//EGL_DEPTH_SIZE, 16,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint context_attributes[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
//
|
||||
// Get Native Display
|
||||
EGLNativeDisplayType nativeDisplay = lvrcSwapChainGetNativeDisplay(compositor);
|
||||
|
||||
if (!nativeDisplay)
|
||||
{
|
||||
fprintf(stderr, "invalid native display\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// get an EGL display connection
|
||||
ctx->display = eglGetDisplay(nativeDisplay);
|
||||
|
||||
if (EGL_NO_DISPLAY == ctx->display)
|
||||
{
|
||||
fprintf(stderr, "eglGetDisplay() failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// initialize the EGL display connection
|
||||
EGLint major, minor;
|
||||
|
||||
if (!eglInitialize(ctx->display, &major, &minor))
|
||||
{
|
||||
fprintf(stderr, "eglInitialize() failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// bind OpenGL API
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
//
|
||||
// get an appropriate EGL frame buffer configuration
|
||||
EGLint num_config;
|
||||
EGLConfig configs[128];
|
||||
|
||||
if (!eglChooseConfig(ctx->display, attribs, configs, 128, &num_config))
|
||||
{
|
||||
fprintf(stderr, "eglChooseConfig() failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
EGLConfig config = configs[0]; // FIXME
|
||||
|
||||
//
|
||||
// create context
|
||||
ctx->context = eglCreateContext(ctx->display, config, EGL_NO_CONTEXT, context_attributes);
|
||||
|
||||
if (EGL_NO_CONTEXT == ctx->context)
|
||||
{
|
||||
fprintf(stderr, "failed to create context\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// Get Native Window
|
||||
EGLNativeWindowType nativeWindow = lvrcSwapChainGetNativeWindow(compositor);
|
||||
|
||||
if (!nativeWindow)
|
||||
{
|
||||
fprintf(stderr, "invalid native window\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// Create Surface
|
||||
ctx->surface = eglCreateWindowSurface(ctx->display, config, nativeWindow, NULL);
|
||||
if (EGL_NO_SURFACE == ctx->surface)
|
||||
{
|
||||
fprintf(stderr, "eglCreateWindowSurface() failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// Set current context
|
||||
if (!eglMakeCurrent(ctx->display, ctx->surface, ctx->surface, ctx->context))
|
||||
{
|
||||
fprintf(stderr, "failed to make context current\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ctx->w = lvrcSwapChainGetWidth(compositor);
|
||||
ctx->h = lvrcSwapChainGetHeight(compositor);
|
||||
ctx->is_fullscreen = 1;
|
||||
|
||||
// Disable ctrl-c catching on Linux (and OS X?)
|
||||
#ifdef __unix
|
||||
signal(SIGINT, SIG_DFL);
|
||||
#endif
|
||||
|
||||
printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
|
||||
printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
|
||||
printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
|
||||
|
||||
// == Initialize OpenGL ==
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glLoadIdentity();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glEnable(GL_POLYGON_SMOOTH);
|
||||
glLoadIdentity();
|
||||
|
||||
glViewport(0, 0, ctx->w, ctx->h);
|
||||
}
|
||||
|
||||
void ortho(gl_ctx* ctx)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
//glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0.0f, ctx->w, ctx->h, 0.0f, -1.0f, 1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
//glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_DEPTH);
|
||||
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
void draw_cube()
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Top) */
|
||||
glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Top) */
|
||||
glVertex3f( -0.5f, 0.5f, 0.5f); /* Bottom Left Of The Quad (Top) */
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f); /* Bottom Right Of The Quad (Top) */
|
||||
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f); /* Top Right Of The Quad (Botm) */
|
||||
glVertex3f( -0.5f, -0.5f, 0.5f); /* Top Left Of The Quad (Botm) */
|
||||
glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Botm) */
|
||||
glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Botm) */
|
||||
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f); /* Top Right Of The Quad (Front) */
|
||||
glVertex3f( -0.5f, 0.5f, 0.5f); /* Top Left Of The Quad (Front) */
|
||||
glVertex3f( -0.5f, -0.5f, 0.5f); /* Bottom Left Of The Quad (Front) */
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f); /* Bottom Right Of The Quad (Front) */
|
||||
|
||||
glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Back) */
|
||||
glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Back) */
|
||||
glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Back) */
|
||||
glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Back) */
|
||||
|
||||
glVertex3f( -0.5f, 0.5f, 0.5f); /* Top Right Of The Quad (Left) */
|
||||
glVertex3f( -0.5f, 0.5f, -0.5f); /* Top Left Of The Quad (Left) */
|
||||
glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Left) */
|
||||
glVertex3f( -0.5f, -0.5f, 0.5f); /* Bottom Right Of The Quad (Left) */
|
||||
|
||||
glVertex3f( 0.5f, 0.5f, -0.5f); /* Top Right Of The Quad (Right) */
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f); /* Top Left Of The Quad (Right) */
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f); /* Bottom Left Of The Quad (Right) */
|
||||
glVertex3f( 0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Right) */
|
||||
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex)
|
||||
{
|
||||
glGenTextures(1, color_tex);
|
||||
glGenTextures(1, depth_tex);
|
||||
glGenFramebuffers(1, fbo);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, *color_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, eye_width, eye_height, 0, GL_RGBA, GL_UNSIGNED_INT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, *depth_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, eye_width, eye_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_tex, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_tex, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
if(status != GL_FRAMEBUFFER_COMPLETE_EXT){
|
||||
printf("failed to create fbo %x\n", status);
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
34
examples/opengl/gl.h
Normal file
34
examples/opengl/gl.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* OpenHMD - Free and Open Source API and drivers for immersive technology.
|
||||
* Copyright (C) 2013 Fredrik Hultin.
|
||||
* Copyright (C) 2013 Jakob Bornecrantz.
|
||||
* Distributed under the Boost 1.0 licence, see LICENSE for full text.
|
||||
*/
|
||||
|
||||
/* OpenGL Test - Interface For GL Helper Functions */
|
||||
|
||||
#ifndef GL_H
|
||||
#define GL_H
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#include <lvrc.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned int w, h;
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
int is_fullscreen;
|
||||
} gl_ctx;
|
||||
|
||||
void ortho(gl_ctx* ctx);
|
||||
void perspective(gl_ctx* ctx);
|
||||
void init_gl(gl_ctx* ctx, struct lvrcInstance * compositor);
|
||||
void draw_cube(void);
|
||||
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex);
|
||||
|
||||
|
||||
#endif
|
||||
355
examples/opengl/main.c
Normal file
355
examples/opengl/main.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* OpenHMD - Free and Open Source API and drivers for immersive technology.
|
||||
* Copyright (C) 2013 Fredrik Hultin.
|
||||
* Copyright (C) 2013 Jakob Bornecrantz.
|
||||
* Distributed under the Boost 1.0 licence, see LICENSE for full text.
|
||||
*/
|
||||
|
||||
/* OpenGL Test - Main Implementation */
|
||||
|
||||
#include <openhmd.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gl.h"
|
||||
|
||||
#define OVERSAMPLE_SCALE 2.0
|
||||
|
||||
float randf()
|
||||
{
|
||||
return (float)rand() / (float)RAND_MAX;
|
||||
}
|
||||
|
||||
GLuint gen_cubes()
|
||||
{
|
||||
GLuint list = glGenLists(1);
|
||||
|
||||
// Set the random seed.
|
||||
srand(42);
|
||||
|
||||
glNewList(list, GL_COMPILE);
|
||||
|
||||
for(float a = 0.0f; a < 360.0f; a += 20.0f){
|
||||
glPushMatrix();
|
||||
|
||||
glRotatef(a, 0, 1, 0);
|
||||
glTranslatef(0, 0, -1);
|
||||
glScalef(0.2, 0.2, 0.2);
|
||||
glRotatef(randf() * 360, randf(), randf(), randf());
|
||||
|
||||
glColor4f(randf(), randf(), randf(), randf() * .5f + .5f);
|
||||
draw_cube();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// draw floor
|
||||
glColor4f(0, 1.0f, .25f, .25f);
|
||||
glTranslatef(0, -2.5f, 0);
|
||||
draw_cube();
|
||||
|
||||
glEndList();
|
||||
|
||||
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
|
||||
glCallList(list);
|
||||
}
|
||||
static inline void
|
||||
print_matrix(float m[])
|
||||
{
|
||||
printf("[[%0.4f, %0.4f, %0.4f, %0.4f],\n"
|
||||
"[%0.4f, %0.4f, %0.4f, %0.4f],\n"
|
||||
"[%0.4f, %0.4f, %0.4f, %0.4f],\n"
|
||||
"[%0.4f, %0.4f, %0.4f, %0.4f]]\n",
|
||||
m[0], m[4], m[8], m[12],
|
||||
m[1], m[5], m[9], m[13],
|
||||
m[2], m[6], m[10], m[14],
|
||||
m[3], m[7], m[11], m[15]);
|
||||
}
|
||||
|
||||
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){
|
||||
printf("failed to probe devices: %s\n", ohmd_ctx_get_error(ctx));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ohmd_device_settings* settings = ohmd_device_settings_create(ctx);
|
||||
|
||||
// If OHMD_IDS_AUTOMATIC_UPDATE is set to 0, ohmd_ctx_update() must be called at least 10 times per second.
|
||||
// It is enabled by default.
|
||||
|
||||
int auto_update = 1;
|
||||
ohmd_device_settings_seti(settings, OHMD_IDS_AUTOMATIC_UPDATE, &auto_update);
|
||||
|
||||
ohmd_device* hmd = ohmd_list_open_device_s(ctx, 0, settings);
|
||||
if(!hmd){
|
||||
printf("failed to open device: %s\n", ohmd_ctx_get_error(ctx));
|
||||
return 1;
|
||||
}
|
||||
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];
|
||||
float sep;
|
||||
float left_lens_center[2];
|
||||
float right_lens_center[2];
|
||||
//viewport is half the screen
|
||||
ohmd_device_getf(hmd, OHMD_SCREEN_HORIZONTAL_SIZE, &(viewport_scale[0]));
|
||||
viewport_scale[0] /= 2.0f;
|
||||
ohmd_device_getf(hmd, OHMD_SCREEN_VERTICAL_SIZE, &(viewport_scale[1]));
|
||||
//distortion coefficients
|
||||
ohmd_device_getf(hmd, OHMD_UNIVERSAL_DISTORTION_K, &(distortion_coeffs[0]));
|
||||
ohmd_device_getf(hmd, OHMD_UNIVERSAL_ABERRATION_K, &(aberr_scale[0]));
|
||||
//calculate lens centers (assuming the eye separation is the distance between the lens centers)
|
||||
ohmd_device_getf(hmd, OHMD_LENS_HORIZONTAL_SEPARATION, &sep);
|
||||
ohmd_device_getf(hmd, OHMD_LENS_VERTICAL_POSITION, &(left_lens_center[1]));
|
||||
ohmd_device_getf(hmd, OHMD_LENS_VERTICAL_POSITION, &(right_lens_center[1]));
|
||||
left_lens_center[0] = viewport_scale[0] - sep/2.0f;
|
||||
right_lens_center[0] = sep/2.0f;
|
||||
//assume 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);
|
||||
|
||||
struct lvrcInstance * compositor = lvrcCreateInstance(hmd);
|
||||
|
||||
gl_ctx gl;
|
||||
init_gl(&gl, compositor);
|
||||
|
||||
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_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_w, eye_h, &right_fbo, &right_color_tex, &right_depth_tex);
|
||||
|
||||
bool bCompositorInit = lvrcInitFrameResources(compositor);
|
||||
|
||||
if (!bCompositorInit)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
bool crosshair_overlay = false;
|
||||
while(!done){
|
||||
ohmd_ctx_update(ctx);
|
||||
|
||||
lvrcBeginFrame(compositor);
|
||||
|
||||
#if 0
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)){
|
||||
if(event.type == SDL_KEYDOWN){
|
||||
switch(event.key.keysym.sym){
|
||||
case SDLK_ESCAPE:
|
||||
done = true;
|
||||
break;
|
||||
case SDLK_F1:
|
||||
{
|
||||
gl.is_fullscreen = !gl.is_fullscreen;
|
||||
SDL_SetWindowFullscreen(gl.window, gl.is_fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
|
||||
}
|
||||
break;
|
||||
case SDLK_F2:
|
||||
{
|
||||
// reset rotation and position
|
||||
float zero[] = {0, 0, 0, 1};
|
||||
ohmd_device_setf(hmd, OHMD_ROTATION_QUAT, zero);
|
||||
ohmd_device_setf(hmd, OHMD_POSITION_VECTOR, zero);
|
||||
}
|
||||
break;
|
||||
case SDLK_F3:
|
||||
{
|
||||
float mat[16];
|
||||
ohmd_device_getf(hmd, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX, mat);
|
||||
printf("Projection L: ");
|
||||
print_matrix(mat);
|
||||
printf("\n");
|
||||
ohmd_device_getf(hmd, OHMD_RIGHT_EYE_GL_PROJECTION_MATRIX, mat);
|
||||
printf("Projection R: ");
|
||||
print_matrix(mat);
|
||||
printf("\n");
|
||||
ohmd_device_getf(hmd, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX, mat);
|
||||
printf("View: ");
|
||||
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("distortion 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", 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
// Common scene state
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
float matrix[16];
|
||||
|
||||
// set hmd rotation, for left eye.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
ohmd_device_getf(hmd, OHMD_LEFT_EYE_GL_PROJECTION_MATRIX, matrix);
|
||||
glLoadMatrixf(matrix);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
ohmd_device_getf(hmd, OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX, matrix);
|
||||
glLoadMatrixf(matrix);
|
||||
|
||||
// Draw scene into framebuffer.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, left_fbo);
|
||||
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);
|
||||
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);
|
||||
ohmd_device_getf(hmd, OHMD_RIGHT_EYE_GL_PROJECTION_MATRIX, matrix);
|
||||
glLoadMatrixf(matrix);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
ohmd_device_getf(hmd, OHMD_RIGHT_EYE_GL_MODELVIEW_MATRIX, matrix);
|
||||
glLoadMatrixf(matrix);
|
||||
|
||||
// Draw scene into framebuffer.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, right_fbo);
|
||||
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);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// Draw left eye
|
||||
lvrcSubmitFrameLeft(compositor, left_color_tex);
|
||||
|
||||
// Draw right eye
|
||||
lvrcSubmitFrameRight(compositor, right_color_tex);
|
||||
|
||||
// Clean up state.
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glUseProgram(0);
|
||||
|
||||
// Da swap-dawup!
|
||||
eglSwapBuffers(gl.display, gl.surface);
|
||||
|
||||
lvrcEndFrame(compositor);
|
||||
}
|
||||
|
||||
lvrcReleaseFrameResources(compositor);
|
||||
|
||||
// TODO : destroy OpenGL context here
|
||||
|
||||
lvrcReleaseSwapChain(compositor);
|
||||
|
||||
lvrcDestroyInstance(compositor);
|
||||
|
||||
ohmd_ctx_destroy(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user