OVR: Add Support for Oculus Rift SDK
authorAndreas Eversberg <jolly@eversberg.eu>
Sat, 7 Apr 2018 11:44:12 +0000 (13:44 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Sat, 14 Apr 2018 08:56:18 +0000 (10:56 +0200)
16 files changed:
.gitignore
configure.ac
src/Makefile.am
src/libovr/Makefile.am [new file with mode: 0755]
src/libovr/helper.cpp [new file with mode: 0644]
src/libovr/helper.h [new file with mode: 0644]
src/libovr/ovr.c [new file with mode: 0755]
src/libovr/ovr.h [new file with mode: 0755]
src/libsdl/opengl.c
src/libsdl/opengl.h
src/libsdl/sdl.c
src/libsdl/sdl.h
src/mercenary/Makefile.am
src/mercenary/main.c
src/mercenary/render.c
src/mercenary/render.h

index c30d88e..0afa595 100644 (file)
@@ -25,6 +25,7 @@ src/libcpu/m68kmake
 src/libframerate/libframerate.a
 src/libglew/libglew.a
 src/libsdl/libsdl.a
+src/libovr/libovr.a
 src/libvideo/libvideo.a
 src/libsound/libsound.a
 src/libjoystick/libjoystick.a
index dd16624..8ff6fd4 100644 (file)
@@ -46,10 +46,12 @@ AM_CONDITIONAL(WINDOWS, test "x$build_windows" == "xyes" )
 
 AC_ARG_WITH([sdl2], [AS_HELP_STRING([--with-sdl2], [compile with SDL2 library @<:@default=check@:>@]) ], [], [with_sdl2="check"])
 #AC_ARG_WITH([glew], [AS_HELP_STRING([--with-glew], [compile with GLEW library @<:@default=check@:>@]) ], [], [with_glew="check"])
+AC_ARG_WITH([ovr], [AS_HELP_STRING([--with-ovr], [compile with LibOVR library @<:@default=no@:>@]) ], [], [with_ovr="check"])
 AS_IF([test "x$with_sdl2" != xno], [PKG_CHECK_MODULES([SDL2], sdl2 >= 2.0, with_sdl2=yes, with_sdl2=no)])
 #AS_IF([test "x$with_glew" != xno], [PKG_CHECK_MODULES([GLEW], glew >= 1.13, with_glew=yes, with_glew=no)])
 AM_CONDITIONAL(HAVE_SDL2, test "x$with_sdl2" == "xyes" )
 #AM_CONDITIONAL(HAVE_GLEW, test "x$with_glew" == "xyes" )
+AM_CONDITIONAL(HAVE_OVR, test "x$with_ovr" == "xyes" )
 AS_IF([test "x$with_sdl2" == "xyes"],[AC_MSG_NOTICE( Compiling with SDL2 support )], [AC_MSG_NOTICE( [ SDL2 not supported.
       
 Consider adjusting the PKG_CONFIG_PATH environment variable, if you installed software in a non-standard prefix.
@@ -66,6 +68,7 @@ NOTE: This package is mandatory. The games will not compile without it!
 #NOTE: This package is mandatory. The games will not compile without it!
 #***********************************************************************
 #] )])
+AS_IF([test "x$with_ovr" == "xyes"],[AC_MSG_NOTICE( Compiling with OVR support )], [AC_MSG_NOTICE( [OVR not supported.] )])
 
 AC_OUTPUT(
     src/libcpu/Makefile
@@ -77,6 +80,7 @@ AC_OUTPUT(
     src/libdisk/Makefile
     src/libsdl/Makefile
     src/libglew/Makefile
+    src/libovr/Makefile
     src/libtext/Makefile
     src/mercenary/Makefile
     src/Makefile
index 2570804..c695a08 100644 (file)
@@ -13,7 +13,12 @@ SUBDIRS = \
 
 if HAVE_SDL2
 SUBDIRS += \
-          libsdl
+       libsdl
+endif
+
+if HAVE_OVR
+SUBDIRS += \
+       libovr
 endif
 
 SUBDIRS += \
diff --git a/src/libovr/Makefile.am b/src/libovr/Makefile.am
new file mode 100755 (executable)
index 0000000..e1c7c50
--- /dev/null
@@ -0,0 +1,9 @@
+#note that -DGLEW_NO_GLU -DGLEW_BUILD is required, or the framebuffer stuff will not link
+AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) -I../libglew/ -DGLEW_NO_GLU -DGLEW_BUILD
+
+noinst_LIBRARIES = libovr.a
+
+libovr_a_SOURCES = \
+       helper.cpp \
+       ovr.c
+
diff --git a/src/libovr/helper.cpp b/src/libovr/helper.cpp
new file mode 100644 (file)
index 0000000..dd3c044
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include <Extras/OVR_Math.h>
+using namespace OVR;
+#include "helper.h"
+
+void ovrOrientation2yawpitchroll(ovrQuatf orientation, float *yaw, float *pitch, float *roll)
+{
+       Quatf orient = orientation;
+       orient.GetYawPitchRoll(yaw, pitch, roll);
+}
+
diff --git a/src/libovr/helper.h b/src/libovr/helper.h
new file mode 100644 (file)
index 0000000..db89b82
--- /dev/null
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ovrOrientation2yawpitchroll(ovrQuatf orientation, float *yaw, float *pitch, float *roll);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
diff --git a/src/libovr/ovr.c b/src/libovr/ovr.c
new file mode 100755 (executable)
index 0000000..79fd874
--- /dev/null
@@ -0,0 +1,342 @@
+/* OVR handling
+ *
+ * (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
+ * All Rights Reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Based on example code:
+ * Filename    :   main.cpp
+ * Content     :   Simple minimal VR demo
+ * Created     :   December 1, 2014
+ * Author      :   Tom Heath
+ * Copyright   :   Copyright 2012 Oculus, Inc. All Rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include "../libsdl/print.h"
+#include "ovr.h"
+
+#include <OVR_CAPI.h>
+#include <OVR_CAPI_GL.h>
+#include "helper.h"
+
+#define GL3_PROTOTYPES 1
+#include <GL/glew.h>
+
+#if 0
+#if defined(_WIN32)
+    #include <dxgi.h> // for GetDefaultAdapterLuid
+    #pragma comment(lib, "dxgi.lib")
+#endif
+
+static ovrGraphicsLuid GetDefaultAdapterLuid()
+{
+       ovrGraphicsLuid luid = ovrGraphicsLuid();
+
+#if defined(_WIN32)
+       IDXGIFactory* factory = nullptr;
+
+       if (SUCCEEDED(CreateDXGIFactory(IID_PPV_ARGS(&factory)))) {
+               IDXGIAdapter* adapter = nullptr;
+
+               if (SUCCEEDED(factory->EnumAdapters(0, &adapter))) {
+                       DXGI_ADAPTER_DESC desc;
+
+                       adapter->GetDesc(&desc);
+                       memcpy(&luid, &desc.AdapterLuid, sizeof(luid));
+                       adapter->Release();
+               }
+
+               factory->Release();
+       }
+#endif
+
+       return luid;
+}
+
+static int Compare(const ovrGraphicsLuid lhs, const ovrGraphicsLuid rhs)
+{
+    return memcmp(&lhs, &rhs, sizeof(ovrGraphicsLuid));
+}
+#endif
+
+static int ovr_initialized = 0;
+static ovrSession session = NULL;
+static ovrGraphicsLuid luid;
+static ovrHmdDesc hmdDesc;
+static ovrSizei TextureSize[2];
+static ovrTextureSwapChain textureSwapChain[2] = { NULL, NULL };
+static GLuint fboId[2] = { 0, 0 };
+static ovrEyeRenderDesc eyeRenderDesc[2];
+static ovrPosef hmdToEyeViewPose[2];
+static ovrLayerEyeFov layer;
+static long long frameIndex = 0;
+
+int init_ovr(void)
+{
+       int sample_count = 1; // FIXME: make MSAA
+       ovrResult result;
+       int eye;
+
+       glewExperimental = GL_TRUE;
+       if (glewInit() != GLEW_OK) {
+               print_error("Failed to init GLEW\n");
+               goto error;
+       }
+
+       result = ovr_Initialize(NULL);
+       if (OVR_FAILURE(result)) {
+               print_error("Failed to init OVR (is Oculus Rift service running?)\n");
+               goto error;
+       }
+       ovr_initialized = 1;
+
+       result = ovr_Create(&session, &luid);
+       if (OVR_FAILURE(result)) {
+               print_error("Failed to create OVR session (is the HMD connected?)\n");
+               goto error;
+       }
+
+#if 0
+       if (Compare(luid, GetDefaultAdapterLuid())) { // If luid that the Rift is on is not the default adapter LUID...
+               print_error("OpenGL supports only the default graphics adapter.\n");
+               goto error;
+       }
+#endif
+
+       hmdDesc = ovr_GetHmdDesc(session);
+
+       memset(&layer, 0, sizeof(layer));
+       layer.Header.Type      = ovrLayerType_EyeFov;
+       layer.Header.Flags     = 0;
+
+       /* 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;
+
+               memset(&desc, 0, sizeof(desc));
+               desc.Type = ovrTexture_2D;
+               desc.ArraySize = 1;
+               desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+               desc.Width = TextureSize[eye].w;
+               desc.Height = TextureSize[eye].h;
+               desc.MipLevels = 1;
+               desc.SampleCount = sample_count;
+               desc.StaticImage = ovrFalse;
+
+               result = ovr_CreateTextureSwapChainGL(session, &desc, &textureSwapChain[eye]);
+               if (OVR_FAILURE(result)) {
+                       print_error("ovr_CreateTextureSwapChainGL() failed!\n");
+                       goto error;
+               }
+
+               ovr_GetTextureSwapChainLength(session, textureSwapChain[eye], &length);
+               for (i = 0; i < length; i++) {
+                       ovr_GetTextureSwapChainBufferGL(session, textureSwapChain[eye], i, &chainTexId);
+                       glBindTexture(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);
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+               }
+
+               glGenFramebuffers(1, &(fboId[eye]));
+
+               eyeRenderDesc[eye] = ovr_GetRenderDesc(session, (eye == 0) ? ovrEye_Left : ovrEye_Right, hmdDesc.DefaultEyeFov[eye]);
+               hmdToEyeViewPose[eye] = eyeRenderDesc[eye].HmdToEyePose;
+
+               layer.ColorTexture[eye]  = textureSwapChain[eye];
+               layer.Fov[eye]           = eyeRenderDesc[eye].Fov;
+               layer.Viewport[eye].Pos.x = 0;
+               layer.Viewport[eye].Pos.y = 0;
+               layer.Viewport[eye].Size.w = TextureSize[eye].w;
+               layer.Viewport[eye].Size.h = TextureSize[eye].h;
+       }
+
+
+       return 0;
+
+error:
+       exit_ovr();
+       return -EINVAL;
+}
+
+void begin_render_ovr(void)
+{      
+       ovrResult result;
+
+       /* Get both eye poses simultaneously, with IPD offset already included. */
+       double displayMidpointSeconds = ovr_GetPredictedDisplayTime(session, 0);
+       ovrTrackingState hmdState = ovr_GetTrackingState(session, displayMidpointSeconds, ovrTrue);
+       ovr_CalcEyePoses(hmdState.HeadPose.ThePose, hmdToEyeViewPose, layer.RenderPose);
+
+       result = ovr_WaitToBeginFrame(session, frameIndex);
+       if (!OVR_SUCCESS(result))
+               print_info("Failed to wait to begin frame (error %d)\n", result);
+       result = ovr_BeginFrame(session, frameIndex);
+       if (!OVR_SUCCESS(result))
+               print_info("Failed to begin frame (error %d)\n", result);
+}
+
+void begin_render_ovr_eye(int eye)
+{
+       int curIndex;
+       GLuint chainTexId;
+       float yaw, pitch, roll;
+       double x, y, z;
+
+       /* set render surface */
+       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);
+
+       glViewport(0, 0, TextureSize[eye].w, TextureSize[eye].h);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glFrustum(
+               -layer.Fov[eye].LeftTan,
+               layer.Fov[eye].RightTan,
+               layer.Fov[eye].UpTan,
+               -layer.Fov[eye].DownTan,
+               1.0, 5000000000.0);
+
+       ovrOrientation2yawpitchroll(layer.RenderPose[eye].Orientation, &yaw, &pitch, &roll);
+       x = layer.RenderPose[eye].Position.x;
+       y = layer.RenderPose[eye].Position.y;
+       z = layer.RenderPose[eye].Position.z;
+
+       glRotatef(-roll / M_PI * 180.0,0,0,1);
+       glRotatef(-pitch / M_PI * 180.0,1,0,0);
+       glRotatef(-yaw / M_PI * 180.0,0,1,0);
+
+       glTranslated(-x / 0.0254, -y / 0.0254, -z / 0.0254); /* convert to inch */
+
+       glMatrixMode(GL_MODELVIEW);
+
+       /* DO NOT ENABLE, since our mercenary-textures are not SRGB */
+       //glEnable(GL_FRAMEBUFFER_SRGB);
+
+}
+
+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);
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+       // Commit the changes to the texture swap chain
+       ovr_CommitTextureSwapChain(session, textureSwapChain[eye]);
+}
+
+void end_render_ovr(void)
+{
+       ovrResult result;
+
+       const ovrLayerHeader *layers[] = { &layer.Header };
+       result = ovr_EndFrame(session, frameIndex, NULL, layers, 1);
+       if (!OVR_SUCCESS(result))
+               print_info("Failed to submit frame (error %d)\n", result);
+       frameIndex++;
+}
+
+void render_mirror_ovr(int view_width, int view_height)
+{
+       int eye = 0; /* left eye */
+       int curIndex;
+       GLuint chainTexId;
+
+       /* clear screen */
+       glClearColor(1.0, 0.0, 0.0, 1.0);
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       /* orthogonal viewport */
+       glViewport((GLsizei)0, (GLsizei)0, (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);
+}
+
+void exit_ovr(void)
+{
+       int eye;
+
+       /* destroy render buffers */
+       for (eye = 0; eye < 2; eye++) {
+               if (textureSwapChain[eye]) {
+                       ovr_DestroyTextureSwapChain(session, textureSwapChain[eye]);
+                       textureSwapChain[eye] = NULL;
+               }
+               if (fboId[eye]) {
+                       glDeleteFramebuffers(1, &fboId[eye]);
+                       fboId[eye] = 0;
+               }
+       }
+
+       if (session) {
+               ovr_Destroy(session);
+               session = NULL;
+       }
+       if (ovr_initialized) {
+               ovr_Shutdown();
+               ovr_initialized = 0;
+       }
+}
+
diff --git a/src/libovr/ovr.h b/src/libovr/ovr.h
new file mode 100755 (executable)
index 0000000..68aa6d5
--- /dev/null
@@ -0,0 +1,9 @@
+
+int init_ovr(void);
+void exit_ovr(void);
+void begin_render_ovr(void);
+void begin_render_ovr_eye(int eye);
+void end_render_ovr_eye(int eye);
+void end_render_ovr(void);
+void render_mirror_ovr(int view_width, int view_height);
+
index f795cf2..9a6578c 100644 (file)
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
 #include <errno.h>
 #include "print.h"
 #include "opengl.h"
+#define GL3_PROTOTYPES 1
 #include <GL/glew.h>
 
 #define MAX_OSD 2
-static uint8_t *legacy_rgb = NULL;
-static uint8_t *benson_rgb = NULL;
+#define MONITOR_DISTANCE 35.0
+static uint8_t *image_rgb = NULL;
 static uint8_t *osd_rgba[MAX_OSD] = { NULL, NULL };
-static GLuint legacy_name;
-static GLuint benson_name;
+static GLuint image_name;
 static GLuint osd_name[MAX_OSD];
 static int screen_width, screen_height;
 static int image_width, image_height;
 static int osd_width[MAX_OSD], osd_height[MAX_OSD];
 static int texture_size;
 static int osd_size[MAX_OSD];
+static int flip_y;
 
 /* alloc and init an image texture with size that is greater than the power of two */
-int init_opengl(int _image_width, int _image_height)
+int init_opengl_image(int _image_width, int _image_height)
 {
        int rc;
 
@@ -51,34 +53,20 @@ int init_opengl(int _image_width, int _image_height)
        for (texture_size = 1; texture_size <= image_width || texture_size <= image_height; texture_size *= 2)
                ;
 
-       legacy_rgb = calloc(texture_size * texture_size, 3);
-       if (!legacy_rgb) {
+       image_rgb = calloc(texture_size * texture_size, 3);
+       if (!image_rgb) {
                print_error("Failed to allocate texture\n");
                rc = -ENOMEM;
                goto error;
        }
        glShadeModel(GL_FLAT);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* bytes */
-       glGenTextures(1, &legacy_name);
-       glBindTexture(GL_TEXTURE_2D, legacy_name);
+       glGenTextures(1, &image_name);
+       glBindTexture(GL_TEXTURE_2D, image_name);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGB, GL_UNSIGNED_BYTE, legacy_rgb);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGB, GL_UNSIGNED_BYTE, image_rgb);
 
-       benson_rgb = calloc(texture_size * texture_size, 3);
-       if (!benson_rgb) {
-               print_error("Failed to allocate texture\n");
-               rc = -ENOMEM;
-               goto error;
-       }
-
-       glShadeModel(GL_FLAT);
-       glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* bytes */
-       glGenTextures(1, &benson_name);
-       glBindTexture(GL_TEXTURE_2D, benson_name);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGB, GL_UNSIGNED_BYTE, benson_rgb);
 
        return 0;
 
@@ -88,7 +76,7 @@ error:
 }
 
 /* alloc and init an osd texture with size that is greater than the power of two */
-int init_osd(int num, int _osd_width, int _osd_height)
+int init_opengl_osd(int num, int _osd_width, int _osd_height)
 {
        int rc;
 
@@ -120,6 +108,7 @@ int init_osd(int num, int _osd_width, int _osd_height)
        return 0;
 
 error:
+       exit_opengl();
        return rc;
 }
 
@@ -130,102 +119,38 @@ void resize_opengl(int _screen_width, int _screen_height)
        screen_height = _screen_height;
 }
 
-void opengl_clear(void)
+void opengl_clear(int _flip_y)
 {
+       flip_y = _flip_y;
+
        /* clear screen */
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 }
 
-/* set viewport for legacy image */
-void opengl_viewport_legacy(int split)
+/* set viewport for improved rendering */
+void opengl_viewport(int split, int benson_at_line, double fov, double benson_size)
 {
        int view_x, view_y;
        int view_width, view_height;
        int new_width, new_height;
 
-       if (!split) {
-               view_x = 0;
-               view_y = 0;
-               view_width = screen_width;
-               view_height = screen_height;
-       } else {
+       /* center view, or put it in the top half of the window */
+       if (split == 1) {
                view_x = 0;
                view_y = screen_height / 2;
                view_width = screen_width;
                view_height = screen_height / 2;
-       }
-
-       /* 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 image_width:image_height */
-       if (view_height * image_width > view_width * image_height) {
-               new_height = view_width * image_height / image_width;
-               view_y = view_y + view_height / 2 - new_height / 2;
-               view_height = new_height;
-       } else if (view_height * image_width < view_width * image_height) {
-               new_width = view_height * image_width / image_height;
-               view_x = view_x + view_width / 2 - new_width / 2;
-               view_width = new_width;
-       }
-
-       /* avoid views that are too small */
-       if (view_width < 1 || view_height < 1)
-               return;
-
-       /* viewport and projection matrix to view rectangle */
-       glViewport((GLsizei)view_x, (GLsizei)view_y, (GLsizei)view_width, (GLsizei)view_height);
-       glMatrixMode(GL_PROJECTION);
-       glLoadIdentity();
-       glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
-       glMatrixMode(GL_MODELVIEW);
-}
-
-/* render legacy image texture */
-void opengl_blit_legacy(uint8_t *rgb, int filter)
-{
-       double width = (double)image_width / (double)texture_size;
-       double height = (double)image_height / (double)texture_size;
-
-       glEnable(GL_TEXTURE_2D);
-       glBindTexture(GL_TEXTURE_2D, legacy_name);
-       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  /* no modulation with color */
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (filter) ? GL_LINEAR : GL_NEAREST);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (filter) ? GL_LINEAR : GL_NEAREST);
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, rgb);
-       glBegin(GL_QUADS);
-       glTexCoord2f(0.0, 0.0);
-       glVertex3f(0.0, 0.0, 0.0);
-       glTexCoord2f(width, 0.0);
-       glVertex3f(1.0, 0.0, 0.0);
-       glTexCoord2f(width, height);
-       glVertex3f(1.0, 1.0, 0.0);
-       glTexCoord2f(0.0, height);
-       glVertex3f(0.0, 1.0, 0.0);
-       glEnd();
-       glDisable(GL_TEXTURE_2D);
-}
-
-/* set viewport for improved rendering */
-void opengl_viewport_improved(int split, int benson_at_line, double fov, double benson_size)
-{
-       int view_x, view_y;
-       int view_width, view_height;
-       int new_width, new_height;
-
-       /* center view, or put it in the top half of the window */
-       if (!split) {
+       } else if (split == 2) {
                view_x = 0;
                view_y = 0;
                view_width = screen_width;
-               view_height = screen_height;
+               view_height = screen_height / 2;
        } else {
                view_x = 0;
                view_y = 0;
                view_width = screen_width;
-               view_height = screen_height / 2;
+               view_height = screen_height;
        }
 
        /* avoid division by zero, if one dimension is too small */
@@ -261,47 +186,55 @@ void opengl_viewport_improved(int split, int benson_at_line, double fov, double
        double top = slope * ((double)image_height - benson_start_at_position) / (double)image_width;
        double bottom = -slope * ((double)image_height * 2.0 - ((double)image_height - benson_start_at_position)) / (double)image_width;
        glFrustum(left, right, bottom, top, 1.0, 5000000000.0);
+
        glMatrixMode(GL_MODELVIEW);
 }
 
-/* render only benson */
-void opengl_blit_benson(uint8_t *rgb, int filter, int benson_at_line, double fov, double benson_size, int pixel_size)
+/* render image or only benson */
+void opengl_blit_image(uint8_t *rgb, int filter, int benson_at_line, int render_benson_only, double fov, double monitor_distance, double benson_size)
 {
-       double border = (benson_size != 1.0) ? (double)pixel_size : 0.0;
-       double texture_left = border / (double)texture_size;
-       double texture_right = ((double)image_width - border) / (double)texture_size;
-       double texture_top = ((double)benson_at_line + border) / (double)texture_size;
-       double texture_bottom = ((double)image_height -border) / (double)texture_size;
-       double benson_start_at_position = ((double)image_height - (double)benson_at_line) * benson_size;
-       double benson_top = -((double)image_height - benson_start_at_position) / (double)image_width;
-       double benson_bottom = -((double)image_height * 2.0 - ((double)image_height - benson_start_at_position)) / (double)image_width;
+       double texture_left = 0;
+       double texture_right = ((double)image_width) / (double)texture_size;
+       double texture_top = ((double)benson_at_line) / (double)texture_size;
+       double texture_bottom = ((double)image_height) / (double)texture_size;
+       double image_start_at_position = ((double)image_height - (double)benson_at_line) * benson_size;
+       double image_top = -((double)image_height - image_start_at_position) / (double)image_width;
+       double image_bottom = -((double)image_height * 2.0 - ((double)image_height - image_start_at_position)) / (double)image_width;
 
        /* calculate field-of-view */
-       double slope = tan(fov / 360 * M_PI);
+       double slope = tan(fov / 360 * M_PI) * monitor_distance;
 
-       /* render benson */
-       rgb += image_width * benson_at_line * 3;
+       /* render image */
        glEnable(GL_TEXTURE_2D);
-       glBindTexture(GL_TEXTURE_2D, benson_name);
+       glBindTexture(GL_TEXTURE_2D, image_name);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  /* no modulation with color */
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (filter) ? GL_LINEAR : GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (filter) ? GL_LINEAR : GL_NEAREST);
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, benson_at_line, image_width, image_height - benson_at_line, GL_RGB, GL_UNSIGNED_BYTE, rgb);
+       if (render_benson_only) {
+               /* render benson only, and copy top line of benson to one line above, so the texture filter will not take false data above benson */
+               rgb += image_width * (benson_at_line - 1) * 3;
+               memcpy(rgb, rgb + image_width * 3, image_width * 3);
+               glTexSubImage2D(GL_TEXTURE_2D, 0, 0, benson_at_line - 1, image_width, image_height - benson_at_line - 1, GL_RGB, GL_UNSIGNED_BYTE, rgb);
+       } else {
+               image_top = -image_top;
+               texture_top = 0.0;
+               glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, rgb);
+       }
        glBegin(GL_QUADS);
        glTexCoord2f(texture_left, texture_bottom);
-       glVertex3f(-100.0 * benson_size, 100.0 * benson_bottom, -100.0 / slope);
+       glVertex3f(-benson_size * slope, image_bottom * slope, -monitor_distance);
        glTexCoord2f(texture_right, texture_bottom);
-       glVertex3f(100.0 * benson_size, 100.0 * benson_bottom, -100.0 / slope);
+       glVertex3f(benson_size * slope, image_bottom * slope, -monitor_distance);
        glTexCoord2f(texture_right, texture_top);
-       glVertex3f(100.0 * benson_size, 100.0 * benson_top, -100.0 / slope);
+       glVertex3f(benson_size * slope, image_top * slope, -monitor_distance);
        glTexCoord2f(texture_left, texture_top);
-       glVertex3f(-100.0 * benson_size, 100.0 * benson_top, -100.0 / slope);
+       glVertex3f(-benson_size * slope, image_top * slope, -monitor_distance);
        glEnd();
        glDisable(GL_TEXTURE_2D);
 }
 
 /* render osd texture */
-void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, double fov, double benson_size, double scale_x, double scale_y, double offset_x, double offset_y)
+void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, double fov, double monitor_distance, double benson_size, double scale_x, double scale_y, double offset_x, double offset_y)
 {
        double texture_left = 0.0;
        double texture_right = (double)osd_width[num] / (double)osd_size[num];
@@ -320,7 +253,7 @@ void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, dou
                osd_top = ((double)image_height - benson_start_at_position) / (double)image_width;
                osd_bottom = -((double)image_height * 2.0 - ((double)image_height - benson_start_at_position)) / (double)image_width;
                /* calculate field-of-view */
-               slope = tan(fov / 360 * M_PI);
+               slope = tan(fov / 360 * M_PI) * monitor_distance;
        }
        range = (osd_right - osd_left) / 2.0;
        center = (osd_right + osd_left) / 2.0;
@@ -343,13 +276,13 @@ void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, dou
        if (fov) {
                /* perspective viewport */
                glTexCoord2f(texture_left, texture_bottom);
-               glVertex3f(100.0 * osd_left, 100.0 * osd_bottom, -100.0 / slope);
+               glVertex3f(osd_left * slope, osd_bottom * slope, -monitor_distance);
                glTexCoord2f(texture_right, texture_bottom);
-               glVertex3f(100.0 * osd_right, 100.0 * osd_bottom, -100.0 / slope);
+               glVertex3f(osd_right * slope, osd_bottom * slope, -monitor_distance);
                glTexCoord2f(texture_right, texture_top);
-               glVertex3f(100.0 * osd_right, 100.0 * osd_top, -100.0 / slope);
+               glVertex3f(osd_right * slope, osd_top * slope, -monitor_distance);
                glTexCoord2f(texture_left, texture_top);
-               glVertex3f(100.0 * osd_left, 100.0 * osd_top, -100.0 / slope);
+               glVertex3f(osd_left * slope, osd_top * slope, -monitor_distance);
        } else {
                /* orthogonal viewport */
                glTexCoord2f(texture_left, texture_top);
@@ -386,7 +319,7 @@ void opengl_render_polygon(double *x, double *y, double *z, int count, int cull_
 
        if (cull_face) {
                glEnable(GL_CULL_FACE);
-               glFrontFace(GL_CW);
+               glFrontFace((flip_y) ? GL_CCW : GL_CW);
                glCullFace(GL_BACK);
        }
        glBegin(GL_POLYGON);
@@ -440,13 +373,9 @@ void exit_opengl(void)
 {
        int i;
 
-       if (legacy_rgb) {
-               free(legacy_rgb);
-               legacy_rgb = NULL;
-       }
-       if (benson_rgb) {
-               free(benson_rgb);
-               benson_rgb = NULL;
+       if (image_rgb) {
+               free(image_rgb);
+               image_rgb = NULL;
        }
        for (i = 0; i < MAX_OSD; i++) {
                if (osd_rgba[i]) {
index cd7fb38..6a731a9 100644 (file)
@@ -1,13 +1,11 @@
 
-int init_opengl(int _image_width, int _image_height);
-int init_osd(int num, int _osd_width, int _osd_height);
+int init_opengl_image(int _image_width, int _image_height);
+int init_opengl_osd(int num, int _osd_width, int _osd_height);
 void resize_opengl(int _screen_width, int _screen_height);
-void opengl_clear(void);
-void opengl_viewport_legacy(int top);
-void opengl_blit_legacy(uint8_t *rgb, int filter);
-void opengl_viewport_improved(int bottom, int benson_at_line, double fov, double benson_size);
-void opengl_blit_benson(uint8_t *rgb, int filter, int benson_at_line, double fov, double benson_size, int pixel_size);
-void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, double fov, double benson_size, double scale_x, double scale_y, double offset_x, double offset_y);
+void opengl_clear(int flip_y);
+void opengl_viewport(int split, int benson_at_line, double fov, double benson_size); 
+void opengl_blit_image(uint8_t *rgb, int filter, int benson_at_line, int render_benson_only, double fov, double monitor_distance, double benson_size);
+void opengl_blit_osd(int num, uint8_t *rgba, int filter, int benson_at_line, double fov, double monitor_distnace, double benson_size, double scale_x, double scale_y, double offset_x, double offset_y);
 void opengl_render_color(double r, double g, double b, double a);
 void opengl_render_polygon(double *x, double *y, double *z, int count, int cull_face);
 void opengl_render_polygon_and_line(double *x, double *y, double *z, int count);
index 14e5440..b3d78b7 100644 (file)
@@ -44,7 +44,7 @@ static void audio_cb(void __attribute__((unused)) *userdata, Uint8 *stream, int
        SDL_MixAudio(stream, (Uint8 *)audio_data, len, SDL_MIX_MAXVOLUME);
 }
 
-int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), int multisampling)
+int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), int multisampling, int vbl_sync)
 {
        int rc;
 
@@ -108,7 +108,7 @@ int init_sdl(const char *progname, int width, int height, int sound_samplerate,
                goto error;
        }
 
-       rc = SDL_GL_SetSwapInterval(1);
+       rc = SDL_GL_SetSwapInterval((vbl_sync) ? 1 : 0);
        if (rc < 0) {
                print_error("Failed to set SDL's OpenGL swap interval to VBLANK\n");
                // continue anyway
index f44dc22..83882d8 100644 (file)
@@ -82,7 +82,7 @@ enum keycode {
        KEYCODE_INSERT,
 };
 
-int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), int multisampling);
+int init_sdl(const char *progname, int width, int height, int sound_samplerate, int sound_chunk, void (*keyboard)(int down, enum keycode keycode), void (*audio)(float *data, int len), int multisampling, int vbl_sync);
 int event_sdl(void);
 void swap_sdl(void);
 void exit_sdl(void);
index 5de5d7d..82f51f7 100644 (file)
@@ -24,8 +24,7 @@ mercenary2_LDADD = \
        $(top_builddir)/src/libdisk/libdisk.a \
        $(top_builddir)/src/libkeyboard/libkeyboard.a \
        $(top_builddir)/src/libsdl/libsdl.a \
-       $(SDL2_LIBS) \
-       /usr/i686-w64-mingw32/lib/libopengl32.a
+       $(SDL2_LIBS)
 
 mercenary3_SOURCES = \
        mercenary3.c \
@@ -43,8 +42,13 @@ mercenary3_LDADD = \
        $(top_builddir)/src/libdisk/libdisk.a \
        $(top_builddir)/src/libkeyboard/libkeyboard.a \
        $(top_builddir)/src/libsdl/libsdl.a \
-       $(SDL2_LIBS) \
-       /usr/i686-w64-mingw32/lib/libopengl32.a
+       $(SDL2_LIBS)
+
+if HAVE_OVR
+mercenary2_LDADD += $(top_builddir)/src/libovr/libovr.a -llibovr
+mercenary3_LDADD += $(top_builddir)/src/libovr/libovr.a -llibovr
+AM_CPPFLAGS += -DHAVE_OVR
+endif
 
 mercenary2_LDADD += \
        $(top_builddir)/src/libglew/libglew.a
index a0c0040..c94708b 100644 (file)
@@ -24,6 +24,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include "../libsdl/sdl.h"
+#ifdef HAVE_OVR
+#include "../libovr/ovr.h"
+#endif
 #include "../libsdl/opengl.h"
 #include "../libsdl/print.h"
 #include "../libcpu/m68k.h"
@@ -55,6 +58,7 @@ static int config_render = 1; /* opengl render */
 static int config_skip_intro = 0;
 static int config_multisampling = 16;
 static double config_fov = FOV_NOVAGEN;
+static double config_monitor_distance = 31.5; /* inch */
 static double config_benson_size = 1.0;
 static int config_debug_transparent = 0;
 static int config_debug_opengl = 0;
@@ -88,8 +92,13 @@ static uint8_t *help_osd = NULL;
 static uint8_t *info_osd = NULL;
 static int help_view = 1;
 static int32_t osd_timer = 0;
-#define SCREEN_WIDTH   320
-#define SCREEN_HEIGHT  200
+#ifdef HAVE_OVR
+#define SCREEN_WIDTH   800
+#define SCREEN_HEIGHT  800
+#else
+#define SCREEN_WIDTH   (320*3)
+#define SCREEN_HEIGHT  (200*3)
+#endif
 #define IMAGE_WIDTH    320
 #define IMAGE_HEIGHT   200
 #define BENSON_AT_LINE 136
@@ -300,7 +309,6 @@ static void main_loop(void)
 {
        double frame_step, frame_time = 0.0, frame_render = 1;
        int had_first_irq = 0;
-       int render_improved_rc;
        static uint32_t current_time, last_time = 0, diff;
        int i, rc;
        int space, length;
@@ -308,6 +316,7 @@ static void main_loop(void)
        double render_delay = 0.0;
        uint32_t palette_address;
        uint16_t palette[16];
+       int eye;
 
        last_time = ticks_sdl();
 
@@ -329,9 +338,6 @@ static void main_loop(void)
                if (rc)
                        break;
 
-               /* clear screen */
-               opengl_clear();
-
                /* initialize rendering */
                debug_opengl = config_debug_opengl;
                benson_size = config_benson_size;
@@ -341,8 +347,6 @@ static void main_loop(void)
                        /* be sure to clean all capture history, so we don't get glichtes when turning on improved rendering again */
                        render_capture_reset();
                }
-               if (render_improved)
-                       opengl_viewport_improved(debug_opengl, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size);
                /* STEP 1: let the CPU render/process the game, also improve rendering via OpenGL, if enabled */
                /* amgia speed: don't render if we still delay */
                /* non amiga speed: render if we need a new frame */
@@ -378,11 +382,81 @@ static void main_loop(void)
                        if (config_amiga_speed)
                                render_delay += (double)cycle_count / CPU_SPEED;
                }
-               /* render improved graphics, interpolate, if required */
-               if (render_improved)
-                       render_improved_rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time);
-               else
-                       render_improved_rc = -1;
+
+               /* STEP 2: transfer legacy image (or just benson) in memory to OpenGL texture */
+#ifdef HAVE_OVR
+               begin_render_ovr();
+               for (eye = 0; eye < 2; eye++) {
+                       /* viewport and frustum is set here */
+                       begin_render_ovr_eye(eye);
+#else
+               eye = 0;
+               {
+#endif
+                       /* clear screen */
+#ifdef HAVE_OVR
+                       opengl_clear(1);
+#else
+                       opengl_clear(0);
+#endif
+                       /* render benson + osd ontop of improved opengl rendering, if enabled */
+                       if (render_improved) {
+#ifndef HAVE_OVR
+                               /* viewport and frustum is set here */
+                               opengl_viewport((debug_opengl) ? 2 : 0, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size);
+#endif
+                               /* render improved graphics, interpolate, if required,
+                                * if no item list is available, for legacy rendering
+                                */
+#ifdef HAVE_OVR
+                               rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 1);
+#else
+                               rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 0);
+#endif
+                               if (rc)
+                                       goto goto_legacy;
+                               opengl_blit_image(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, 1, config_fov, config_monitor_distance, benson_size);
+                               if (help_view)
+                                       opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, benson_size, 1.0, 1.0, 0.0, 0.0);
+                               if (osd_timer) {
+                                       opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, benson_size, 0.5, 0.04, 0.5, -0.95);
+                                       if (osd_timer - (int32_t)ticks_sdl() < 0)
+                                               osd_timer = 0;
+                               }
+                       }
+                       /* setup viewport for legacy image and render image, if enabled */
+                       /* also render legacy, if render_improved failed due to not (yet) available items */
+                       if (render_legacy) {
+                               goto_legacy:
+                               /* render game view without benson
+                                * because benson is not updated before VBL IRQ, we don't want old image from double buffer
+                                */
+                               if (had_first_irq)
+                                       emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_pixel_size);
+#ifndef HAVE_OVR
+                               /* viewport and frustum is set here */
+                               opengl_viewport((debug_opengl) ? 1 : 0, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, 1.0);
+#endif
+                               opengl_blit_image(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, 0, config_fov, config_monitor_distance, 1.0);
+                               if (help_view)
+                                       opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, 1.0, 1.0, 1.0, 0.0, 0.0);
+                               if (osd_timer) {
+                                       opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, 1.0, 0.5, 0.04, 0.5, -0.95);
+                                       if (osd_timer - (int32_t)ticks_sdl() < 0)
+                                               osd_timer = 0;
+                               }
+                       }
+#ifdef HAVE_OVR
+                       end_render_ovr_eye(eye);
+               }
+               /* at this point we are ready with our image, so we display */
+               end_render_ovr();
+               render_mirror_ovr(SCREEN_WIDTH, SCREEN_HEIGHT);
+#else
+               }
+#endif
+               swap_sdl();
+
                /* advance frame time, if we are not in help view  */
                if (!(had_first_irq && help_view)) {
                        frame_time += frame_step;
@@ -392,41 +466,6 @@ static void main_loop(void)
                        }
                }
 
-               /* STEP 2: transfer legacy image (or just benson) in memory to OpenGL texture */
-               if (had_first_irq) {
-                       /* render game view without benson
-                        * because benson is not updated before VBL IRQ, we don't want old image from double buffer
-                        */
-                       if (render_legacy || render_improved_rc)
-                               emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_pixel_size);
-               }
-               /* render benson + osd ontop of improved opengl rendering, if enabled */
-               if (render_improved && render_improved_rc == 0) {
-                       opengl_blit_benson(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, (double_pixel_size) ? 2 : 1);
-                       if (help_view)
-                               opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, 1.0, 1.0, 0.0, 0.0);
-                       if (osd_timer) {
-                               opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, 0.5, 0.04, 0.5, -0.95);
-                               if (osd_timer - (int32_t)ticks_sdl() < 0)
-                                       osd_timer = 0;
-                       }
-               }
-               /* setup viewport for legacy image and render image, if enabled */
-               /* also render legacy, if render_improved failed due to not (yet) available items */
-               if (render_legacy || (render_improved && render_improved_rc)) {
-                       opengl_viewport_legacy(debug_opengl);
-                       opengl_blit_legacy(image, config_video_filter);
-                       if (help_view)
-                               opengl_blit_osd(0, help_osd, config_video_filter, 0, 0.0, 0, 1.0, 1.0, 0.0, 0.0);
-                       if (osd_timer) {
-                               opengl_blit_osd(1, info_osd, config_video_filter, 0, 0.0, 0, 0.5, 0.04, 0.5, -0.95);
-                               if (osd_timer - (int32_t)ticks_sdl() < 0)
-                                       osd_timer = 0;
-                       }
-               }
-
-               /* at this point we are ready with our image, so we display */
-               swap_sdl();
                /* measure frame rate */
                framerate_measure();
 
@@ -546,7 +585,7 @@ static void disk_read(int track, int __attribute__((unused)) side, uint32_t data
                fp = fopen(filename, "r");
                if (!fp) {
 fail:
-                       print_error("failed to load game from '%s'\n", filename);
+                       print_info("failed to load game from '%s'\n", filename);
                        goto copy;
                }
                got = fread(game_save, sizeof(game_save[0]), 2, fp);
@@ -663,7 +702,7 @@ static void keyboard_sdl(int down, enum keycode keycode)
                        osd_info("render mode", (config_render) ? "OpenGL" : "original");
                        break;
                case KEYCODE_b:
-                       if (!config_render) {
+                       if (!config_render && !config_debug_opengl) {
                                osd_info("", "not applicable");
                                break;
                        }
@@ -947,19 +986,29 @@ int main(int argc, char *argv[])
        mercenary_patch();
 
        /* init SDL and OpenGL */
-       rc = init_sdl(argv[0], (config_debug_opengl) ? SCREEN_WIDTH * 2 : SCREEN_WIDTH * 3, (config_debug_opengl) ? SCREEN_HEIGHT * 4 : SCREEN_HEIGHT * 3, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, config_multisampling);
+#ifdef HAVE_OVR
+       int vbl_sync = 0;
+#else
+       int vbl_sync = 1;
+#endif
+       rc = init_sdl(argv[0], (config_debug_opengl) ? SCREEN_WIDTH / 3 * 2 : SCREEN_WIDTH, (config_debug_opengl) ? SCREEN_HEIGHT / 3 * 4 : SCREEN_HEIGHT, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, config_multisampling, vbl_sync);
        if (rc < 0)
                goto done;
-       rc = init_opengl((double_pixel_size) ? IMAGE_WIDTH * 2 : IMAGE_WIDTH, (double_pixel_size) ? IMAGE_HEIGHT * 2 : IMAGE_HEIGHT);
+#ifdef HAVE_OVR
+       rc = init_ovr();
        if (rc < 0)
                goto done;
-       resize_opengl((config_debug_opengl) ? SCREEN_WIDTH * 2 : SCREEN_WIDTH * 3, (config_debug_opengl) ? SCREEN_HEIGHT * 4 : SCREEN_HEIGHT * 3);
+#endif
+       rc = init_opengl_image((double_pixel_size) ? IMAGE_WIDTH * 2 : IMAGE_WIDTH, (double_pixel_size) ? IMAGE_HEIGHT * 2 : IMAGE_HEIGHT);
+       if (rc < 0)
+               goto done;
+       resize_opengl((config_debug_opengl) ? SCREEN_WIDTH / 3 * 2 : SCREEN_WIDTH, (config_debug_opengl) ? SCREEN_HEIGHT / 3 * 4 : SCREEN_HEIGHT);
 
        /* init osd */
-       rc = init_osd(0, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2);
+       rc = init_opengl_osd(0, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2);
        if (rc < 0)
                goto done;
-       rc = init_osd(1, OSD_WIDTH, OSD_HEIGHT);
+       rc = init_opengl_osd(1, OSD_WIDTH, OSD_HEIGHT);
        if (rc < 0)
                goto done;
        help_osd = text_alloc(IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, HELP_ALPHA);
@@ -1026,6 +1075,9 @@ int main(int argc, char *argv[])
 
 done:
        exit_opengl();
+#ifdef HAVE_OVR
+       exit_ovr();
+#endif
        exit_sdl();
 
        if (chipreg)
index cd93995..673d413 100644 (file)
@@ -38,7 +38,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
-#include <GL/glew.h>
 #include "../libsdl/print.h"
 #include "../libcpu/m68k.h"
 #include "../libcpu/m68kcpu.h"
@@ -46,6 +45,9 @@
 #include "../libsdl/opengl.h"
 #include "mercenary.h"
 
+#define GL3_PROTOTYPES 1
+#include <GL/glew.h>
+
 //#define DEBUG_COLOR
 //#define DEBUG_VERTEX
 //#define DEBUG_ITEMS
@@ -1595,7 +1597,7 @@ static int use_interior_coord(const char __attribute__((unused)) *what, uint32_t
 }
 
 /* renders one item from render list */
-void render_one_item(render_item_t *render_item)
+void render_one_item(render_item_t *render_item, int vr)
 {
        switch (render_item->type) {
        case RENDER_ITEM_OBJECT_INFO:
@@ -2591,7 +2593,7 @@ static render_item_t *interpolate_planets(double inter)
  * use inter 0.0 .. 1.0 to interpolate motion between OLD and NEW items
  * return 0, if the scene was rendered, returns < 0, if there is no scene
  */
-int render_all_items(double inter)
+int render_all_items(double inter, int vr)
 {
        render_item_object_info = NULL;
        render_item_vertices_0 = render_item_vertices_1 = render_item_vertices_2 = NULL;
@@ -2654,7 +2656,7 @@ int render_all_items(double inter)
                return -1;
 
        for (render_item = render_list_new; render_item; render_item = render_item->next) {
-               render_one_item(render_item);
+               render_one_item(render_item, vr);
        }
 
        return 0;
index 6ff93e7..ed230c8 100644 (file)
@@ -2,7 +2,7 @@
 void render_capture_start(double _fov, int _extend_roads, int debug);
 void render_capture_stop(void);
 void render_capture_event(int event);
-int render_all_items(double inter);
+int render_all_items(double inter, int vr);
 void render_capture_reset(void);
 int render_capture_is_interstellar(void);