texcoord2f[2] = 1;texcoord2f[3] = 0;
texcoord2f[4] = 1;texcoord2f[5] = 1;
texcoord2f[6] = 0;texcoord2f[7] = 1;
- R_Mesh_Draw(0, 4, 2, polygonelements);
+ if (vid.stereobuffer)
+ {
+ qglDrawBuffer(GL_BACK_LEFT);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ qglDrawBuffer(GL_BACK_RIGHT);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ }
+ else
+ {
+ qglDrawBuffer(GL_BACK);
+ R_Mesh_Draw(0, 4, 2, polygonelements);
+ }
R_Mesh_Finish();
// refresh
VID_Finish(false);
if (r_timereport_active)
R_TimeReport("clear");
- if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
+ if (vid.stereobuffer || r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
{
matrix4x4_t originalmatrix = r_view.matrix;
r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_view.matrix.m[0][1];
r_view.colormask[2] = 0;
}
+ if (vid.stereobuffer)
+ qglDrawBuffer(GL_BACK_RIGHT);
+
SCR_DrawScreen();
r_view.matrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_view.matrix.m[0][1];
r_view.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
}
+ if (vid.stereobuffer)
+ qglDrawBuffer(GL_BACK_LEFT);
+
SCR_DrawScreen();
r_view.matrix = originalmatrix;
}
else
+ {
+ qglDrawBuffer(GL_BACK);
SCR_DrawScreen();
+ }
SCR_CaptureVideo();
#define GL_TEXTURE_COORD_ARRAY 0x8078
//#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_NONE 0
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
+#define GL_LEFT 0x0406
+#define GL_RIGHT 0x0407
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_AUX0 0x0409
+#define GL_AUX1 0x040A
+#define GL_AUX2 0x040B
+#define GL_AUX3 0x040C
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
0 bug darkplaces loader: occasional crash due to memory corruption when doing "deathmatch 1;map start" during demo loop (Willis)
0 bug darkplaces loader: q3bsp deluxemap detection can fail on some files, thinking they have deluxemaps even though they don't? (jimmmy)
0 bug darkplaces loader: q3bsp lightgrid loading seems to be ignoring the "gridsize" key of worldspawn, but how?
+0 bug darkplaces physics: GAME_TAOV: Vigil's movement isn't working properly, the qc uses MOVETYPE_STEP and clears FL_ONGROUND every frame and moves using velocity, this is causing a landing sound every frame and causing the player to slide down minor slopes very quickly, this did not occur in Quake, and seems that it must be related to a velocity_z check or FL_ONGROUND check in the MOVETYPE_STEP physics code (RenegadeC, xaGe)
0 bug darkplaces physics: in Prydon Gate the func_door2 entities are stuck in eachother, causing a continuous spew of warnings and causing one of them to be teleported slightly upward which looks bad (FrikaC)
0 bug darkplaces readme: commandline options are slightly out of date, update them (Baker)
+0 bug darkplaces readme: it would be a very good idea to add documentation of sv_gameplayfix_* cvars in the readme as a means to run broken mods (xaGe)
0 bug darkplaces renderer: GL13 path has broken handling of unlit surfaces in Nexuiz toxic.bsp - the small red light surfaces are black in GL13 path (m0rfar)
0 bug darkplaces renderer: modify r_showtris_polygonoffset to push back all filled geometry, not lines, because polygonoffset will not affect GL_LINES at all
0 bug darkplaces renderer: monsters teleporting in really slow down rendering, perhaps the teleport light is casting huge shadows? new information suggests it is the particles. (romi, lcatlnx)
int bitsperpixel;
int fullscreen;
int refreshrate;
+ int stereobuffer;
} viddef_t;
// global video state
// sets the mode; only used by the Quake engine for resetting to mode 0 (the
// base mode) on memory allocation failures
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate);
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer);
// allocates and opens an appropriate OpenGL context (and its window)
Sys_Quit();
}
-static void VID_BuildAGLAttrib(GLint *attrib, qboolean stencil, qboolean fullscreen)
+static void VID_BuildAGLAttrib(GLint *attrib, qboolean stencil, qboolean fullscreen, qboolean stereobuffer)
{
*attrib++ = AGL_RGBA;
*attrib++ = AGL_RED_SIZE;*attrib++ = 1;
}
if (fullscreen)
*attrib++ = AGL_FULLSCREEN;
+ if (stereobuffer)
+ *attrib++ = AGL_STEREO;
*attrib++ = AGL_NONE;
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
const EventTypeSpec winEvents[] =
{
GetEventTypeCount(winEvents), winEvents, window, NULL);
// Create the desired attribute list
- VID_BuildAGLAttrib(attributes, bpp == 32, fullscreen);
+ VID_BuildAGLAttrib(attributes, bpp == 32, fullscreen, stereobuffer);
if (!fullscreen)
{
mouse_avail = false;
}
-void VID_BuildGLXAttrib(int *attrib, int stencil)
+void VID_BuildGLXAttrib(int *attrib, qboolean stencil, qboolean stereobuffer)
{
*attrib++ = GLX_RGBA;
*attrib++ = GLX_RED_SIZE;*attrib++ = 1;
*attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8;
*attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1;
}
+ if (stereobuffer)
+ *attrib++ = GLX_STEREO;
*attrib++ = None;
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
int i;
int attrib[32];
return false;
}
- VID_BuildGLXAttrib(attrib, bpp == 32);
+ VID_BuildGLXAttrib(attrib, bpp == 32, stereobuffer);
visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib);
if (!visinfo)
{
InitSig(); // trap evil signals
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
return false;
}
version->major, version->minor, version->patch );
}
-int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
int i;
int flags = SDL_OPENGL;
SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 1);
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
}
+ if (stereobuffer)
+ SDL_GL_SetAttribute (SDL_GL_STEREO, 1);
screen = SDL_SetVideoMode(width, height, bpp, flags);
if (screen == NULL)
cvar_t vid_height = {CVAR_SAVE, "vid_height", "480", "resolution"};
cvar_t vid_bitsperpixel = {CVAR_SAVE, "vid_bitsperpixel", "32", "how many bits per pixel to render at (32 or 16, 32 is recommended)"};
cvar_t vid_refreshrate = {CVAR_SAVE, "vid_refreshrate", "60", "refresh rate to use, in hz (higher values flicker less, if supported by your monitor)"};
+cvar_t vid_stereobuffer = {CVAR_SAVE, "vid_stereobuffer", "0", "enables 'quad-buffered' stereo rendering for stereo shutterglasses, HMD (head mounted display) devices, or polarized stereo LCDs, if supported by your drivers"};
cvar_t vid_vsync = {CVAR_SAVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time), automatically disabled when doing timedemo benchmarks"};
cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1", "whether to use the mouse in windowed mode (fullscreen always does)"};
Cvar_RegisterVariable(&vid_height);
Cvar_RegisterVariable(&vid_bitsperpixel);
Cvar_RegisterVariable(&vid_refreshrate);
+ Cvar_RegisterVariable(&vid_stereobuffer);
Cvar_RegisterVariable(&vid_vsync);
Cvar_RegisterVariable(&vid_mouse);
Cvar_RegisterVariable(&vid_minwidth);
Cvar_Set("gl_combine", "0");
}
-int VID_Mode(int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_Mode(int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
- Con_Printf("Video: %s %dx%dx%dx%dhz\n", fullscreen ? "fullscreen" : "window", width, height, bpp, refreshrate);
- if (VID_InitMode(fullscreen, width, height, bpp, refreshrate))
+ Con_Printf("Video: %s %dx%dx%dx%dhz%s\n", fullscreen ? "fullscreen" : "window", width, height, bpp, refreshrate, stereobuffer ? " stereo" : "");
+ if (VID_InitMode(fullscreen, width, height, bpp, refreshrate, stereobuffer))
{
vid.fullscreen = fullscreen;
vid.width = width;
vid.height = height;
vid.bitsperpixel = bpp;
vid.refreshrate = refreshrate;
+ vid.stereobuffer = stereobuffer;
Cvar_SetValueQuick(&vid_fullscreen, fullscreen);
Cvar_SetValueQuick(&vid_width, width);
Cvar_SetValueQuick(&vid_height, height);
Cvar_SetValueQuick(&vid_bitsperpixel, bpp);
Cvar_SetValueQuick(&vid_refreshrate, refreshrate);
+ Cvar_SetValueQuick(&vid_stereobuffer, stereobuffer);
return true;
}
else
vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer);
VID_CloseSystems();
VID_Shutdown();
- if (!VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.integer))
+ if (!VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.integer, vid_stereobuffer.integer))
{
Con_Print("Video mode change failed\n");
- if (!VID_Mode(vid.fullscreen, vid.width, vid.height, vid.bitsperpixel, vid.refreshrate))
+ if (!VID_Mode(vid.fullscreen, vid.width, vid.height, vid.bitsperpixel, vid.refreshrate, vid.stereobuffer))
Sys_Error("Unable to restore to last working video mode");
}
VID_OpenSystems();
}
Con_Print("Starting video system\n");
- success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.integer);
+ success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.integer, vid_stereobuffer.integer);
if (!success)
{
Con_Print("Desired video mode fail, trying fallbacks...\n");
- success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, 60);
+ success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, 60, vid_stereobuffer.integer);
+ if (!success && vid_stereobuffer.integer)
+ success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.integer, false);
if (!success && vid_bitsperpixel.integer > 16)
- success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, 16, 60);
+ success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, 16, 60, false);
if (!success && (vid_width.integer > 640 || vid_height.integer > 480))
- success = VID_Mode(vid_fullscreen.integer, 640, 480, 16, 60);
+ success = VID_Mode(vid_fullscreen.integer, 640, 480, 16, 60, false);
if (!success && vid_fullscreen.integer)
- success = VID_Mode(false, 640, 480, 16, 60);
+ success = VID_Mode(false, 640, 480, 16, 60, false);
if (!success)
Sys_Error("Video modes failed");
}
IN_Init();
}
-int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrate)
+int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrate, int stereobuffer)
{
int i;
HDC hdc;
pfd.cAlphaBits = 0;
}
+ if (stereobuffer)
+ pfd.dwFlags |= PFD_STEREO;
+
gldrivername = "opengl32.dll";
// COMMANDLINEOPTION: Windows WGL: -gl_driver <drivername> selects a GL driver library, default is opengl32.dll, useful only for 3dfxogl.dll or 3dfxvgl.dll, if you don't know what this is for, you don't need it
i = COM_CheckParm("-gl_driver");