234 lines
5.1 KiB
C
234 lines
5.1 KiB
C
/*
|
|
* 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 "gl.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <lvrc.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_scene(GLuint list)
|
|
{
|
|
// draw cubes
|
|
glCallList(list);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
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;
|
|
}
|
|
|
|
int hmd_w = 0;
|
|
int hmd_h = 0;
|
|
ohmd_device_geti(hmd, OHMD_SCREEN_HORIZONTAL_RESOLUTION, &hmd_w);
|
|
ohmd_device_geti(hmd, OHMD_SCREEN_VERTICAL_RESOLUTION, &hmd_h);
|
|
|
|
ohmd_device_settings_destroy(settings);
|
|
|
|
struct lvrcInstance * compositor = lvrcCreateInstance(hmd);
|
|
|
|
if (!compositor)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
const int window_w = hmd_w/2;
|
|
const int window_h = hmd_h;
|
|
|
|
gl_ctx gl;
|
|
init_gl(&gl, window_w, window_h);
|
|
|
|
GLuint list = gen_cubes();
|
|
|
|
bool bCompositorInit = lvrcInitRenderingEGL(compositor, gl.egl_display, gl.egl_context, gl.egl_surface);
|
|
|
|
if (!bCompositorInit)
|
|
{
|
|
printf ("Could not create compositor\n");
|
|
return -1;
|
|
}
|
|
|
|
int eye_w = hmd_w/2*OVERSAMPLE_SCALE;
|
|
int eye_h = hmd_h*OVERSAMPLE_SCALE;
|
|
|
|
GLuint textures [2];
|
|
|
|
bool bSwapChainInit = lvrcInitSwapChain(compositor, eye_w, eye_h, textures);
|
|
|
|
if (!bSwapChainInit)
|
|
{
|
|
printf ("Could not create swapchain\n");
|
|
return -1;
|
|
}
|
|
|
|
GLuint left_color_tex = textures[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 = textures[1], right_depth_tex = 0, right_fbo = 0;
|
|
create_fbo(eye_w, eye_h, &right_fbo, right_color_tex, &right_depth_tex);
|
|
|
|
bool done = false;
|
|
|
|
while (!done)
|
|
{
|
|
ohmd_ctx_update(ctx);
|
|
|
|
lvrcBeginFrame(compositor);
|
|
|
|
eglMakeCurrent(gl.egl_display, gl.egl_surface, gl.egl_surface, gl.egl_context);
|
|
|
|
// 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.
|
|
glBindFramebuffer(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);
|
|
|
|
// 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.
|
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, right_fbo);
|
|
glViewport(0, 0, eye_w, eye_h);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
draw_scene(list);
|
|
|
|
// Clean up common draw state
|
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
// Setup ortho state.
|
|
glViewport(0, 0, window_w, window_h);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glColor4d(1, 1, 1, 1);
|
|
|
|
// Setup simple render state
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// Draw left eye
|
|
glBindTexture(GL_TEXTURE_2D, left_color_tex);
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2d( 0, 0);
|
|
glVertex3d( -1, -1, 1);
|
|
glTexCoord2d( 1, 0);
|
|
glVertex3d( 1, -1, 1);
|
|
glTexCoord2d( 1, 1);
|
|
glVertex3d( 1, 1, 1);
|
|
glTexCoord2d( 0, 1);
|
|
glVertex3d( -1, 1, 1);
|
|
glEnd();
|
|
|
|
// Clean up state.
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glUseProgram(0);
|
|
|
|
// Da swap-dawup!
|
|
eglSwapBuffers(gl.egl_display, gl.egl_surface);
|
|
|
|
lvrcEndFrame(compositor);
|
|
}
|
|
|
|
lvrcDestroyInstance(compositor);
|
|
|
|
ohmd_ctx_destroy(ctx);
|
|
|
|
return 0;
|
|
}
|