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
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.
#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
src/libdisk/Makefile
src/libsdl/Makefile
src/libglew/Makefile
+ src/libovr/Makefile
src/libtext/Makefile
src/mercenary/Makefile
src/Makefile
if HAVE_SDL2
SUBDIRS += \
- libsdl
+ libsdl
+endif
+
+if HAVE_OVR
+SUBDIRS += \
+ libovr
endif
SUBDIRS += \
--- /dev/null
+#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
+
--- /dev/null
+
+#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);
+}
+
--- /dev/null
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ovrOrientation2yawpitchroll(ovrQuatf orientation, float *yaw, float *pitch, float *roll);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
--- /dev/null
+/* 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;
+ }
+}
+
--- /dev/null
+
+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);
+
#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;
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;
}
/* 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;
return 0;
error:
+ exit_opengl();
return rc;
}
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 */
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];
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;
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);
if (cull_face) {
glEnable(GL_CULL_FACE);
- glFrontFace(GL_CW);
+ glFrontFace((flip_y) ? GL_CCW : GL_CW);
glCullFace(GL_BACK);
}
glBegin(GL_POLYGON);
{
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]) {
-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);
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;
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
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);
$(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 \
$(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
#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"
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;
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
{
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;
double render_delay = 0.0;
uint32_t palette_address;
uint16_t palette[16];
+ int eye;
last_time = ticks_sdl();
if (rc)
break;
- /* clear screen */
- opengl_clear();
-
/* initialize rendering */
debug_opengl = config_debug_opengl;
benson_size = config_benson_size;
/* 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 */
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;
}
}
- /* 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();
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);
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;
}
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);
done:
exit_opengl();
+#ifdef HAVE_OVR
+ exit_ovr();
+#endif
exit_sdl();
if (chipreg)
#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"
#include "../libsdl/opengl.h"
#include "mercenary.h"
+#define GL3_PROTOTYPES 1
+#include <GL/glew.h>
+
//#define DEBUG_COLOR
//#define DEBUG_VERTEX
//#define DEBUG_ITEMS
}
/* 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:
* 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;
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;
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);