Update openglexample
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
project (openglexample C)
|
|
||||||
|
|
||||||
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(OpenHMD REQUIRED)
|
find_package(OpenHMD REQUIRED)
|
||||||
|
|
||||||
add_executable(openglexample gl.c gl.h main.c)
|
add_executable(openglexample gl.c gl.h main.c vr_context.c vr_context.h)
|
||||||
|
|
||||||
target_include_directories(openglexample PRIVATE ${OPENGL_INCLUDE_DIRS})
|
target_include_directories(openglexample PRIVATE ${OPENGL_INCLUDE_DIRS})
|
||||||
target_link_libraries(openglexample PRIVATE ${OPENGL_LIBRARIES})
|
target_link_libraries(openglexample PRIVATE ${OPENGL_LIBRARIES})
|
||||||
target_link_libraries(openglexample PRIVATE m)
|
target_link_libraries(openglexample PRIVATE m)
|
||||||
target_link_libraries(openglexample PRIVATE openhmd)
|
target_link_libraries(openglexample PRIVATE openhmd)
|
||||||
target_link_libraries(openglexample PRIVATE lvrc)
|
target_link_libraries(openglexample PRIVATE lvrc)
|
||||||
|
|
||||||
|
target_include_directories(openglexample PRIVATE "/usr/include/drm")
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
#include "gl.h"
|
#include "gl.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <lvrc.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
#ifdef __unix
|
#ifdef __unix
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -23,125 +25,211 @@
|
|||||||
#define M_PI 3.14159265359
|
#define M_PI 3.14159265359
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const uint32_t xcb_window_attrib_mask = XCB_CW_EVENT_MASK;
|
||||||
|
const uint32_t xcb_window_attrib_list[] = {
|
||||||
|
XCB_EVENT_MASK_BUTTON_PRESS,
|
||||||
|
XCB_EVENT_MASK_EXPOSURE,
|
||||||
|
XCB_EVENT_MASK_KEY_PRESS,
|
||||||
|
};
|
||||||
|
|
||||||
void init_gl(gl_ctx* ctx, struct lvrcInstance * compositor)
|
void CreateWindow(const char *display_name,
|
||||||
|
int window_x,
|
||||||
|
int window_y,
|
||||||
|
int window_width,
|
||||||
|
int window_height,
|
||||||
|
xcb_connection_t** out_connection,
|
||||||
|
int* out_screen,
|
||||||
|
xcb_window_t* out_window) {
|
||||||
|
|
||||||
|
xcb_generic_error_t* error;
|
||||||
|
|
||||||
|
//int iscreen;
|
||||||
|
|
||||||
|
xcb_connection_t *connection = xcb_connect(NULL, NULL);
|
||||||
|
if (!connection)
|
||||||
|
exit(-1);
|
||||||
|
if (xcb_connection_has_error(connection))
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
const xcb_setup_t* setup = xcb_get_setup(connection);
|
||||||
|
xcb_screen_t* screen = xcb_setup_roots_iterator(setup).data;
|
||||||
|
assert(screen != 0);
|
||||||
|
|
||||||
|
xcb_window_t window = xcb_generate_id(connection);
|
||||||
|
if (window <= 0)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
xcb_void_cookie_t create_cookie = xcb_create_window_checked(
|
||||||
|
connection,
|
||||||
|
XCB_COPY_FROM_PARENT, // depth
|
||||||
|
window,
|
||||||
|
screen->root, // parent window
|
||||||
|
window_x,
|
||||||
|
window_y,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
0, // border width
|
||||||
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
|
||||||
|
screen->root_visual, // visual
|
||||||
|
xcb_window_attrib_mask,
|
||||||
|
xcb_window_attrib_list);
|
||||||
|
|
||||||
|
xcb_void_cookie_t map_cookie = xcb_map_window_checked(connection, window);
|
||||||
|
|
||||||
|
// Check errors.
|
||||||
|
error = xcb_request_check(connection, create_cookie);
|
||||||
|
if (error)
|
||||||
|
exit(-1);
|
||||||
|
error = xcb_request_check(connection, map_cookie);
|
||||||
|
if (error)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
*out_connection = connection;
|
||||||
|
*out_window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EGLint egl_config_attribs[] = {
|
||||||
|
//EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
|
||||||
|
//EGL_BUFFER_SIZE, 32,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
|
||||||
|
//EGL_DEPTH_SIZE, 24,
|
||||||
|
//EGL_STENCIL_SIZE, 8,
|
||||||
|
|
||||||
|
//EGL_SAMPLE_BUFFERS, 0,
|
||||||
|
//EGL_SAMPLES, 0,
|
||||||
|
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||||
|
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EGLint egl_context_attribs[] = {
|
||||||
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EGLint egl_surface_attribs[] = {
|
||||||
|
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
void CreateContext(
|
||||||
|
EGLint api,
|
||||||
|
EGLNativeWindowType native_window,
|
||||||
|
EGLDisplay* out_display,
|
||||||
|
EGLConfig* out_config,
|
||||||
|
EGLContext* out_context,
|
||||||
|
EGLSurface* out_window_surface) {
|
||||||
|
|
||||||
|
EGLint ignore;
|
||||||
|
EGLBoolean ok;
|
||||||
|
|
||||||
|
ok = eglBindAPI(api);
|
||||||
|
if (!ok)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
if (display == EGL_NO_DISPLAY)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
ok = eglInitialize(display, &ignore, &ignore);
|
||||||
|
if (!ok)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
EGLint configs_size = 256;
|
||||||
|
EGLConfig configs [configs_size];
|
||||||
|
EGLint num_configs;
|
||||||
|
ok = eglChooseConfig(
|
||||||
|
display,
|
||||||
|
egl_config_attribs,
|
||||||
|
configs,
|
||||||
|
configs_size, // num requested configs
|
||||||
|
&num_configs); // num returned configs
|
||||||
|
if (!ok)
|
||||||
|
exit(-1);
|
||||||
|
if (num_configs == 0)
|
||||||
|
exit(-1);
|
||||||
|
EGLConfig config = configs[0];
|
||||||
|
|
||||||
|
EGLContext context = eglCreateContext(
|
||||||
|
display,
|
||||||
|
config,
|
||||||
|
EGL_NO_CONTEXT, // can't share between 2 different drivers
|
||||||
|
egl_context_attribs);
|
||||||
|
if (!context)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
EGLSurface surface = eglCreateWindowSurface(
|
||||||
|
display,
|
||||||
|
config,
|
||||||
|
native_window,
|
||||||
|
egl_surface_attribs);
|
||||||
|
if (!surface)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
ok = eglMakeCurrent(display, surface, surface, context);
|
||||||
|
if (!ok)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
// Check if surface is double buffered.
|
||||||
|
EGLint render_buffer;
|
||||||
|
ok = eglQueryContext(
|
||||||
|
display,
|
||||||
|
context,
|
||||||
|
EGL_RENDER_BUFFER,
|
||||||
|
&render_buffer);
|
||||||
|
if (!ok)
|
||||||
|
exit(-1);
|
||||||
|
if (render_buffer == EGL_SINGLE_BUFFER)
|
||||||
|
printf("warn: EGL surface is single buffered\n");
|
||||||
|
|
||||||
|
*out_display = display;
|
||||||
|
*out_config = config;
|
||||||
|
*out_context = context;
|
||||||
|
*out_window_surface = surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_gl(gl_ctx* ctx, int w, int h)
|
||||||
{
|
{
|
||||||
memset(ctx, 0, sizeof(gl_ctx));
|
memset(ctx, 0, sizeof(gl_ctx));
|
||||||
|
|
||||||
bool bSwapChainCreated = lvrcInitSwapChain(compositor);
|
const char *x_display_name = NULL;
|
||||||
|
|
||||||
if (!bSwapChainCreated)
|
CreateWindow(x_display_name,
|
||||||
|
0, 0, // x, y
|
||||||
|
w, h, // width, height
|
||||||
|
&ctx->x_connection,
|
||||||
|
&ctx->x_screen,
|
||||||
|
&ctx->x_window);
|
||||||
|
|
||||||
|
if(ctx->x_window == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "swap chain not created\n");
|
printf("CreateWindow failed\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const EGLint attribs[] =
|
ctx->w = w;
|
||||||
{
|
ctx->h = h;
|
||||||
EGL_RED_SIZE, 8,
|
ctx->is_fullscreen = 0;
|
||||||
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[] =
|
CreateContext(EGL_OPENGL_API,
|
||||||
{
|
ctx->x_window,
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
&ctx->egl_display,
|
||||||
EGL_NONE
|
&ctx->egl_config,
|
||||||
};
|
&ctx->egl_context,
|
||||||
|
&ctx->egl_surface);
|
||||||
|
|
||||||
//
|
if(ctx->egl_context == EGL_NO_CONTEXT)
|
||||||
// Get Native Display
|
|
||||||
EGLNativeDisplayType nativeDisplay = lvrcSwapChainGetNativeDisplay(compositor);
|
|
||||||
|
|
||||||
if (!nativeDisplay)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "invalid native display\n");
|
printf("CreateContext\n");
|
||||||
exit(-1);
|
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?)
|
// Disable ctrl-c catching on Linux (and OS X?)
|
||||||
#ifdef __unix
|
#ifdef __unix
|
||||||
signal(SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
@@ -227,6 +315,59 @@ void draw_cube()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void compile_shader_src(GLuint shader, const char* src)
|
||||||
|
{
|
||||||
|
glShaderSource(shader, 1, &src, NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
GLint length;
|
||||||
|
char log[4096] = {0};
|
||||||
|
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
glGetShaderInfoLog(shader, 4096, &length, log);
|
||||||
|
if(status == GL_FALSE){
|
||||||
|
printf("compile failed %s\n", log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint compile_shader(const char* vertex, const char* fragment)
|
||||||
|
{
|
||||||
|
// Create the handels
|
||||||
|
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
GLuint programShader = glCreateProgram();
|
||||||
|
|
||||||
|
// Attach the shaders to a program handel.
|
||||||
|
glAttachShader(programShader, vertexShader);
|
||||||
|
glAttachShader(programShader, fragmentShader);
|
||||||
|
|
||||||
|
// Load and compile the Vertex Shader
|
||||||
|
compile_shader_src(vertexShader, vertex);
|
||||||
|
|
||||||
|
// Load and compile the Fragment Shader
|
||||||
|
compile_shader_src(fragmentShader, fragment);
|
||||||
|
|
||||||
|
// The shader objects are not needed any more,
|
||||||
|
// the programShader is the complete shader to be used.
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
|
||||||
|
glLinkProgram(programShader);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
GLint length;
|
||||||
|
char log[4096] = {0};
|
||||||
|
|
||||||
|
glGetProgramiv(programShader, GL_LINK_STATUS, &status);
|
||||||
|
glGetProgramInfoLog(programShader, 4096, &length, log);
|
||||||
|
if(status == GL_FALSE){
|
||||||
|
printf("link failed %s\n", log);
|
||||||
|
}
|
||||||
|
|
||||||
|
return programShader;
|
||||||
|
}
|
||||||
|
|
||||||
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex)
|
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex)
|
||||||
{
|
{
|
||||||
glGenTextures(1, color_tex);
|
glGenTextures(1, color_tex);
|
||||||
@@ -248,14 +389,14 @@ void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, G
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, *fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_tex, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_tex, 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_tex, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_tex, 0);
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||||
|
|
||||||
if(status != GL_FRAMEBUFFER_COMPLETE_EXT){
|
if(status != GL_FRAMEBUFFER_COMPLETE_EXT){
|
||||||
printf("failed to create fbo %x\n", status);
|
printf("failed to create fbo %x\n", status);
|
||||||
}
|
}
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,24 +10,33 @@
|
|||||||
#ifndef GL_H
|
#ifndef GL_H
|
||||||
#define GL_H
|
#define GL_H
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glext.h>
|
#include <GL/glext.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
#include <lvrc.h>
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int w, h;
|
int w, h;
|
||||||
EGLDisplay display;
|
xcb_connection_t* x_connection;
|
||||||
EGLSurface surface;
|
int x_screen;
|
||||||
EGLContext context;
|
xcb_window_t x_window;
|
||||||
|
|
||||||
|
EGLDisplay egl_display;
|
||||||
|
EGLConfig egl_config;
|
||||||
|
EGLContext egl_context;
|
||||||
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
int is_fullscreen;
|
int is_fullscreen;
|
||||||
} gl_ctx;
|
} gl_ctx;
|
||||||
|
|
||||||
void ortho(gl_ctx* ctx);
|
void ortho(gl_ctx* ctx);
|
||||||
void perspective(gl_ctx* ctx);
|
void perspective(gl_ctx* ctx);
|
||||||
void init_gl(gl_ctx* ctx, struct lvrcInstance * compositor);
|
void init_gl(gl_ctx* ctx, int w, int h);
|
||||||
void draw_cube(void);
|
void draw_cube();
|
||||||
|
GLuint compile_shader(const char* vertex, const char* fragment);
|
||||||
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex);
|
void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,14 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "gl.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "gl.h"
|
|
||||||
|
#include <lvrc.h>
|
||||||
|
|
||||||
|
#include "vr_context.h"
|
||||||
|
|
||||||
#define OVERSAMPLE_SCALE 2.0
|
#define OVERSAMPLE_SCALE 2.0
|
||||||
|
|
||||||
@@ -150,7 +155,19 @@ int main(int argc, char** argv)
|
|||||||
struct lvrcInstance * compositor = lvrcCreateInstance(hmd);
|
struct lvrcInstance * compositor = lvrcCreateInstance(hmd);
|
||||||
|
|
||||||
gl_ctx gl;
|
gl_ctx gl;
|
||||||
init_gl(&gl, compositor);
|
init_gl(&gl, hmd_w, hmd_h);
|
||||||
|
|
||||||
|
const char* vertex;
|
||||||
|
ohmd_gets(OHMD_GLSL_DISTORTION_VERT_SRC, &vertex);
|
||||||
|
const char* fragment;
|
||||||
|
ohmd_gets(OHMD_GLSL_DISTORTION_FRAG_SRC, &fragment);
|
||||||
|
|
||||||
|
GLuint shader = compile_shader(vertex, fragment);
|
||||||
|
glUseProgram(shader);
|
||||||
|
glUniform1i(glGetUniformLocation(shader, "warpTexture"), 0);
|
||||||
|
glUniform2fv(glGetUniformLocation(shader, "ViewportScale"), 1, viewport_scale);
|
||||||
|
glUniform3fv(glGetUniformLocation(shader, "aberr"), 1, aberr_scale);
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
GLuint list = gen_cubes();
|
GLuint list = gen_cubes();
|
||||||
|
|
||||||
@@ -162,6 +179,32 @@ int main(int argc, char** argv)
|
|||||||
GLuint right_color_tex = 0, right_depth_tex = 0, right_fbo = 0;
|
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);
|
create_fbo(eye_w, eye_h, &right_fbo, &right_color_tex, &right_depth_tex);
|
||||||
|
|
||||||
|
PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImage = (PFNEGLEXPORTDMABUFIMAGEMESAPROC) eglGetProcAddress("eglExportDMABUFImageMESA");
|
||||||
|
PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQuery = (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) eglGetProcAddress("eglExportDMABUFImageQueryMESA");
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
EGLImage left_image = eglCreateImage(gl.egl_display, gl.egl_context, EGL_GL_TEXTURE_2D, (EGLClientBuffer)(left_color_tex), NULL);
|
||||||
|
|
||||||
|
dma_texture_params left_texture_params;
|
||||||
|
left_texture_params.width = eye_w;
|
||||||
|
left_texture_params.height = eye_h;
|
||||||
|
eglExportDMABUFImageQuery(gl.egl_display, left_image, &left_texture_params.fourcc, &left_texture_params.numplanes, &left_texture_params.modifiers);
|
||||||
|
eglExportDMABUFImage(gl.egl_display, left_image, &left_texture_params.fd, &left_texture_params.stride, &left_texture_params.offset);
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
EGLImage right_image = eglCreateImage(gl.egl_display, gl.egl_context, EGL_GL_TEXTURE_2D, (EGLClientBuffer)(right_color_tex), NULL);
|
||||||
|
|
||||||
|
dma_texture_params right_texture_params;
|
||||||
|
right_texture_params.width = eye_w;
|
||||||
|
right_texture_params.height = eye_h;
|
||||||
|
eglExportDMABUFImageQuery(gl.egl_display, right_image, &right_texture_params.fourcc, &right_texture_params.numplanes, &right_texture_params.modifiers);
|
||||||
|
eglExportDMABUFImage(gl.egl_display, right_image, &right_texture_params.fd, &right_texture_params.stride, &right_texture_params.offset);
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
extern void init_vr_context(struct lvrcInstance * compositor, dma_texture_params * left_texture_params, dma_texture_params * right_texture_params);
|
||||||
|
init_vr_context(compositor, &left_texture_params, &right_texture_params);
|
||||||
|
|
||||||
bool bCompositorInit = lvrcInitFrameResources(compositor);
|
bool bCompositorInit = lvrcInitFrameResources(compositor);
|
||||||
|
|
||||||
if (!bCompositorInit)
|
if (!bCompositorInit)
|
||||||
@@ -172,104 +215,12 @@ int main(int argc, char** argv)
|
|||||||
bool done = false;
|
bool done = false;
|
||||||
bool crosshair_overlay = false;
|
bool crosshair_overlay = false;
|
||||||
while(!done){
|
while(!done){
|
||||||
|
|
||||||
ohmd_ctx_update(ctx);
|
ohmd_ctx_update(ctx);
|
||||||
|
|
||||||
lvrcBeginFrame(compositor);
|
lvrcBeginFrame(compositor);
|
||||||
|
|
||||||
#if 0
|
eglMakeCurrent(gl.egl_display, gl.egl_surface, gl.egl_surface, gl.egl_context);
|
||||||
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
|
// Common scene state
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@@ -286,7 +237,7 @@ int main(int argc, char** argv)
|
|||||||
glLoadMatrixf(matrix);
|
glLoadMatrixf(matrix);
|
||||||
|
|
||||||
// Draw scene into framebuffer.
|
// Draw scene into framebuffer.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, left_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, left_fbo);
|
||||||
glViewport(0, 0, eye_w, eye_h);
|
glViewport(0, 0, eye_w, eye_h);
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
@@ -308,7 +259,7 @@ int main(int argc, char** argv)
|
|||||||
glLoadMatrixf(matrix);
|
glLoadMatrixf(matrix);
|
||||||
|
|
||||||
// Draw scene into framebuffer.
|
// Draw scene into framebuffer.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, right_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, right_fbo);
|
||||||
glViewport(0, 0, eye_w, eye_h);
|
glViewport(0, 0, eye_w, eye_h);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
draw_scene(list);
|
draw_scene(list);
|
||||||
@@ -320,15 +271,52 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clean up common draw state
|
// Clean up common draw state
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
|
||||||
|
// Setup ortho state.
|
||||||
|
glUseProgram(shader);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Setup simple render state
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
// Draw left eye
|
// Draw left eye
|
||||||
lvrcSubmitFrameLeft(compositor, left_color_tex);
|
glUniform2fv(glGetUniformLocation(shader, "LensCenter"), 1, left_lens_center);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, left_color_tex);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2d( 0, 0);
|
||||||
|
glVertex3d( -1, -1, 0);
|
||||||
|
glTexCoord2d( 1, 0);
|
||||||
|
glVertex3d( 0, -1, 0);
|
||||||
|
glTexCoord2d( 1, 1);
|
||||||
|
glVertex3d( 0, 1, 0);
|
||||||
|
glTexCoord2d( 0, 1);
|
||||||
|
glVertex3d( -1, 1, 0);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
// Draw right eye
|
// Draw right eye
|
||||||
lvrcSubmitFrameRight(compositor, right_color_tex);
|
glUniform2fv(glGetUniformLocation(shader, "LensCenter"), 1, right_lens_center);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, right_color_tex);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2d( 0, 0);
|
||||||
|
glVertex3d( 0, -1, 0);
|
||||||
|
glTexCoord2d( 1, 0);
|
||||||
|
glVertex3d( 1, -1, 0);
|
||||||
|
glTexCoord2d( 1, 1);
|
||||||
|
glVertex3d( 1, 1, 0);
|
||||||
|
glTexCoord2d( 0, 1);
|
||||||
|
glVertex3d( 0, 1, 0);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
// Clean up state.
|
// Clean up state.
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
@@ -336,17 +324,18 @@ int main(int argc, char** argv)
|
|||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
// Da swap-dawup!
|
// Da swap-dawup!
|
||||||
eglSwapBuffers(gl.display, gl.surface);
|
eglSwapBuffers(gl.egl_display, gl.egl_surface);
|
||||||
|
|
||||||
|
|
||||||
|
extern void vr_context_submit_eyes(struct lvrcInstance * compositor);
|
||||||
|
|
||||||
|
vr_context_submit_eyes(compositor);
|
||||||
|
|
||||||
lvrcEndFrame(compositor);
|
lvrcEndFrame(compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
lvrcReleaseFrameResources(compositor);
|
lvrcReleaseFrameResources(compositor);
|
||||||
|
|
||||||
// TODO : destroy OpenGL context here
|
|
||||||
|
|
||||||
lvrcReleaseSwapChain(compositor);
|
|
||||||
|
|
||||||
lvrcDestroyInstance(compositor);
|
lvrcDestroyInstance(compositor);
|
||||||
|
|
||||||
ohmd_ctx_destroy(ctx);
|
ohmd_ctx_destroy(ctx);
|
||||||
|
|||||||
214
examples/opengl/vr_context.c
Normal file
214
examples/opengl/vr_context.c
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
#include "vr_context.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
#include <lvrc.h>
|
||||||
|
|
||||||
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
|
static EGLDisplay display;
|
||||||
|
static EGLSurface surface;
|
||||||
|
static EGLContext context;
|
||||||
|
|
||||||
|
static void create_vr_context(struct lvrcInstance * compositor)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
display = eglGetDisplay(nativeDisplay);
|
||||||
|
|
||||||
|
if (EGL_NO_DISPLAY == display)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "eglGetDisplay() failed\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize the EGL display connection
|
||||||
|
EGLint major, minor;
|
||||||
|
|
||||||
|
if (!eglInitialize(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(display, attribs, configs, 128, &num_config))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "eglChooseConfig() failed\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLConfig config = configs[0]; // FIXME
|
||||||
|
|
||||||
|
//
|
||||||
|
// create context
|
||||||
|
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
|
||||||
|
|
||||||
|
if (EGL_NO_CONTEXT == 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
|
||||||
|
surface = eglCreateWindowSurface(display, config, nativeWindow, NULL);
|
||||||
|
if (EGL_NO_SURFACE == surface)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "eglCreateWindowSurface() failed\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set current context
|
||||||
|
if (!eglMakeCurrent(display, surface, surface, context))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to make context current\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint left_color_tex = 0;
|
||||||
|
GLuint right_color_tex = 0;
|
||||||
|
|
||||||
|
void init_vr_context(struct lvrcInstance * compositor, dma_texture_params * left_texture_params, dma_texture_params * right_texture_params)
|
||||||
|
{
|
||||||
|
bool bSwapChainCreated = lvrcInitSwapChain(compositor);
|
||||||
|
|
||||||
|
if (!bSwapChainCreated)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "swap chain not created\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
create_vr_context(compositor);
|
||||||
|
|
||||||
|
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress ("glEGLImageTargetTexture2DOES");
|
||||||
|
|
||||||
|
//
|
||||||
|
// LEFT
|
||||||
|
EGLAttrib attrib_list_left[] =
|
||||||
|
{
|
||||||
|
EGL_DMA_BUF_PLANE0_FD_EXT, left_texture_params->fd,
|
||||||
|
EGL_DMA_BUF_PLANE0_PITCH_EXT, left_texture_params->stride,
|
||||||
|
EGL_DMA_BUF_PLANE0_OFFSET_EXT, left_texture_params->offset,
|
||||||
|
EGL_WIDTH, left_texture_params->width,
|
||||||
|
EGL_HEIGHT, left_texture_params->height,
|
||||||
|
EGL_LINUX_DRM_FOURCC_EXT, left_texture_params->fourcc,
|
||||||
|
//EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, left_texture_params->modifiers & 0xFFFFFFFF,
|
||||||
|
//EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, left_texture_params->modifiers >> 32,
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLImage image_left = eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrib_list_left);
|
||||||
|
|
||||||
|
glGenTextures(1, &left_color_tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, left_color_tex);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_left);
|
||||||
|
assert(glGetError() == GL_NO_ERROR);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// RIGHT
|
||||||
|
EGLAttrib attrib_list_right[] =
|
||||||
|
{
|
||||||
|
EGL_DMA_BUF_PLANE0_FD_EXT, right_texture_params->fd,
|
||||||
|
EGL_DMA_BUF_PLANE0_PITCH_EXT, right_texture_params->stride,
|
||||||
|
EGL_DMA_BUF_PLANE0_OFFSET_EXT, right_texture_params->offset,
|
||||||
|
EGL_WIDTH, right_texture_params->width,
|
||||||
|
EGL_HEIGHT, right_texture_params->height,
|
||||||
|
EGL_LINUX_DRM_FOURCC_EXT, right_texture_params->fourcc,
|
||||||
|
//EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, right_texture_params->modifiers & 0xFFFFFFFF,
|
||||||
|
//EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, right_texture_params->modifiers >> 32,
|
||||||
|
EGL_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLImage image_right = eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrib_list_right);
|
||||||
|
|
||||||
|
glGenTextures(1, &right_color_tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, right_color_tex);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_right);
|
||||||
|
assert(glGetError() == GL_NO_ERROR);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vr_context_submit_eyes(struct lvrcInstance * compositor)
|
||||||
|
{
|
||||||
|
eglMakeCurrent(display, surface, surface, context);
|
||||||
|
|
||||||
|
glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Draw left eye
|
||||||
|
lvrcSubmitFrameLeft(compositor, left_color_tex);
|
||||||
|
|
||||||
|
// Draw right eye
|
||||||
|
lvrcSubmitFrameRight(compositor, right_color_tex);
|
||||||
|
|
||||||
|
eglSwapBuffers(display, surface);
|
||||||
|
}
|
||||||
14
examples/opengl/vr_context.h
Normal file
14
examples/opengl/vr_context.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int stride;
|
||||||
|
int offset;
|
||||||
|
int fourcc;
|
||||||
|
int numplanes;
|
||||||
|
unsigned long int modifiers;
|
||||||
|
} dma_texture_params;
|
||||||
Reference in New Issue
Block a user