From e5f5852bf6c64ade23a1558b3c8f4c21abe5e14f Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 15 Apr 2018 17:13:30 +0200 Subject: [PATCH] OVR: Multisampling Anitaliasing (MSAA) with real mirror view. --- src/libovr/ovr.c | 104 +++++++++++++++++++++++++++++---------------------- src/libovr/ovr.h | 2 +- src/libsdl/sdl.c | 4 +- src/mercenary/main.c | 10 +++-- 4 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/libovr/ovr.c b/src/libovr/ovr.c index 0bc8eb9..80c5a85 100755 --- a/src/libovr/ovr.c +++ b/src/libovr/ovr.c @@ -95,9 +95,13 @@ static ovrHmdDesc hmdDesc; static ovrSizei TextureSize[2]; static ovrTextureSwapChain textureSwapChain[2] = { NULL, NULL }; static GLuint fboId[2] = { 0, 0 }; +static GLuint mirrorFBO = 0; +static int mirror_width; +static int mirror_height; static ovrEyeRenderDesc eyeRenderDesc[2]; static ovrPosef hmdToEyeViewPose[2]; static ovrLayerEyeFov layer; +static int multisampling; static long long frameIndex = 0; static double observer_x = 0.0; static double observer_x_normalize = 0.0; @@ -106,12 +110,13 @@ static double observer_y_normalize = 0.0; static double observer_z = 0.0; static double observer_z_normalize = 0.0; -int init_ovr(void) +int init_ovr(int _multisampling) { - int sample_count = 1; // FIXME: make MSAA ovrResult result; int eye; + multisampling = _multisampling; + glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { print_error("Failed to init GLEW\n"); @@ -144,12 +149,13 @@ int init_ovr(void) layer.Header.Type = ovrLayerType_EyeFov; layer.Header.Flags = 0; + /* do we need this??? seems to work without */ + if (multisampling > 1) + glEnable(GL_MULTISAMPLE); + /* create render buffers */ for (eye = 0; eye < 2; eye++) { TextureSize[eye] = ovr_GetFovTextureSize(session, (eye == 0) ? ovrEye_Left : ovrEye_Right, hmdDesc.DefaultEyeFov[eye], 1.0); -#warning hacking resolution -//TextureSize[eye].w *= 2; -//TextureSize[eye].h *= 2; ovrTextureSwapChainDesc desc; int length, i; GLuint chainTexId; @@ -161,7 +167,7 @@ int init_ovr(void) desc.Width = TextureSize[eye].w; desc.Height = TextureSize[eye].h; desc.MipLevels = 1; - desc.SampleCount = sample_count; + desc.SampleCount = (multisampling > 1) ? multisampling : 1; desc.StaticImage = ovrFalse; result = ovr_CreateTextureSwapChainGL(session, &desc, &textureSwapChain[eye]); @@ -173,7 +179,7 @@ int init_ovr(void) ovr_GetTextureSwapChainLength(session, textureSwapChain[eye], &length); for (i = 0; i < length; i++) { ovr_GetTextureSwapChainBufferGL(session, textureSwapChain[eye], i, &chainTexId); - glBindTexture(GL_TEXTURE_2D, chainTexId); + glBindTexture((multisampling > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, chainTexId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -193,6 +199,33 @@ int init_ovr(void) layer.Viewport[eye].Size.h = TextureSize[eye].h; } + ovrMirrorTexture mirrorTexture = NULL; + ovrMirrorTextureDesc desc; + memset(&desc, 0, sizeof(desc)); + desc.Width = mirror_width = TextureSize[0].w; + desc.Height = mirror_height = TextureSize[0].h / 2; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + desc.MirrorOptions = + ovrMirrorOption_PostDistortion | + ovrMirrorOption_IncludeGuardian | + ovrMirrorOption_IncludeNotifications | + ovrMirrorOption_IncludeSystemGui; + + /* Create mirror texture and an FBO used to copy mirror texture to back buffer */ + result = ovr_CreateMirrorTextureWithOptionsGL(session, &desc, &mirrorTexture); + if (!OVR_SUCCESS(result)) { + print_error("ovr_CreateMirrorTextureWithOptionsGL() failed!\n"); + goto error; + } + + /* Configure the mirror read buffer */ + GLuint texId; + ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &texId); + + glGenFramebuffers(1, &mirrorFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); return 0; @@ -229,7 +262,7 @@ void begin_render_ovr_eye(int eye) ovr_GetTextureSwapChainCurrentIndex(session, textureSwapChain[eye], &curIndex); ovr_GetTextureSwapChainBufferGL(session, textureSwapChain[eye], curIndex, &chainTexId); glBindFramebuffer(GL_FRAMEBUFFER, fboId[eye]); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, chainTexId, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, (multisampling > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, chainTexId, 0); glViewport(0, 0, TextureSize[eye].w, TextureSize[eye].h); glMatrixMode(GL_PROJECTION); @@ -271,8 +304,8 @@ void end_render_ovr_eye(int eye) { // unset render surface glBindFramebuffer(GL_FRAMEBUFFER, fboId[eye]); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, (multisampling > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, (multisampling > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, 0, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Commit the changes to the texture swap chain @@ -294,21 +327,18 @@ void render_mirror_ovr(int view_width, int view_height) { int view_x = 0, view_y = 0; int new_width, new_height; - int eye = 0; /* left eye */ - int curIndex; - GLuint chainTexId; /* avoid division by zero, if one dimension is too small */ if (view_width < 1 || view_height < 1) return; /* calculate a viewport that has apect of TextureSize */ - if (view_height * TextureSize[eye].w > view_width * TextureSize[eye].h) { - new_height = view_width * TextureSize[eye].h / TextureSize[eye].w; + if (view_height * mirror_width > view_width * mirror_height) { + new_height = view_width * mirror_height / mirror_width; view_y = view_y + view_height / 2 - new_height / 2; view_height = new_height; - } else if (view_height * TextureSize[eye].w < view_width * TextureSize[eye].h) { - new_width = view_height * TextureSize[eye].w / TextureSize[eye].h; + } else if (view_height * mirror_width < view_width * mirror_height) { + new_width = view_height * mirror_width / mirror_height; view_x = view_x + view_width / 2 - new_width / 2; view_width = new_width; } @@ -317,36 +347,18 @@ void render_mirror_ovr(int view_width, int view_height) if (view_width < 1 || view_height < 1) return; - /* clear screen */ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - /* orthogonal viewport */ - glViewport((GLsizei)view_x, (GLsizei)view_y, (GLsizei)view_width, (GLsizei)view_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - - /* get texture from OVR */ - ovr_GetTextureSwapChainCurrentIndex(session, textureSwapChain[eye], &curIndex); - ovr_GetTextureSwapChainBufferGL(session, textureSwapChain[eye], curIndex, &chainTexId); - - /* render mirror from texture */ - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, chainTexId); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); /* no modulation with color */ - glBegin(GL_QUADS); - glTexCoord2f(0, 1); - glVertex3f(-1.0, -1.0, 0.0); - glTexCoord2f(1, 1); - glVertex3f(1.0, -1.0, 0.0); - glTexCoord2f(1, 0); - glVertex3f(1.0, 1.0, 0.0); - glTexCoord2f(0, 0); - glVertex3f(-1.0, 1.0, 0.0); - glEnd(); - glDisable(GL_TEXTURE_2D); + /* Blit mirror texture to back buffer */ + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, mirror_height, mirror_width, 0, + view_x, view_y, view_x + view_width, view_y + view_height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } void normalize_observer_ovr(void) @@ -371,6 +383,10 @@ void exit_ovr(void) fboId[eye] = 0; } } + if (mirrorFBO) { + glDeleteFramebuffers(1, &mirrorFBO); + mirrorFBO = 0; + } if (session) { ovr_Destroy(session); diff --git a/src/libovr/ovr.h b/src/libovr/ovr.h index 4b8b8ee..1400127 100755 --- a/src/libovr/ovr.h +++ b/src/libovr/ovr.h @@ -1,5 +1,5 @@ -int init_ovr(void); +int init_ovr(int multisampling); void exit_ovr(void); void begin_render_ovr(void); void begin_render_ovr_eye(int eye); diff --git a/src/libsdl/sdl.c b/src/libsdl/sdl.c index d0eeb78..3e5d7bd 100644 --- a/src/libsdl/sdl.c +++ b/src/libsdl/sdl.c @@ -63,7 +63,7 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate, } sdl_initialized = 1; - if (multisampling) { + if (multisampling > 1) { SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); @@ -132,7 +132,7 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate, /* just in case */ glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); - if (multisampling) + if (multisampling > 1) glEnable(GL_MULTISAMPLE); if (rift) { diff --git a/src/mercenary/main.c b/src/mercenary/main.c index 526dd06..2b4a8a0 100644 --- a/src/mercenary/main.c +++ b/src/mercenary/main.c @@ -56,7 +56,7 @@ static int config_video_filter = 1; static int config_audio_filter = 1; static int config_render = 1; /* opengl render */ static int config_skip_intro = 0; -static int config_multisampling = 16; +static int config_multisampling = 8; static double config_fov = FOV_NOVAGEN; static double config_monitor_distance = 31.5; /* inch */ static double config_benson_size = 1.0; @@ -94,7 +94,7 @@ static uint8_t *info_osd = NULL; static int help_view = 1; static int32_t osd_timer = 0; #ifdef HAVE_OVR -#define SCREEN_WIDTH 672 +#define SCREEN_WIDTH 1344 #define SCREEN_HEIGHT 800 #else #define SCREEN_WIDTH (320*3) @@ -1009,19 +1009,21 @@ int main(int argc, char *argv[]) #ifdef HAVE_OVR int vbl_sync = 0; int rift = 1; + int multisampling = 0; window_width = SCREEN_WIDTH; window_height = SCREEN_HEIGHT; #else int vbl_sync = 1; int rift = 0; + int multisampling = config_multisampling; window_width = (config_debug_opengl) ? SCREEN_WIDTH / 3 * 2 : SCREEN_WIDTH; window_height = (config_debug_opengl) ? SCREEN_HEIGHT / 3 * 4 : SCREEN_HEIGHT; #endif - rc = init_sdl(argv[0], window_width, window_height, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, resize_window, config_multisampling, vbl_sync, rift); + rc = init_sdl(argv[0], window_width, window_height, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, resize_window, multisampling, vbl_sync, rift); if (rc < 0) goto done; #ifdef HAVE_OVR - rc = init_ovr(); + rc = init_ovr(config_multisampling); if (rc < 0) goto done; #endif -- 2.13.6