Hi all,
Please, check out this patch for stereo mode, the game is look just like Nvidia stereo driver.
The patch was generated by diff on Ubuntu Hardy. Please, patch into version 2.4.2 engine source. Enjoy!!!
The codes:
diff -c -d
*** MyDownloads/darkplaces/cl_screen.c 2008-04-10 03:03:36.000000000 -0400
--- darkplaces/cl_screen.c 2008-07-01 08:25:30.000000000 -0400
***************
*** 36,47 ****
cvar_t cl_capturevideo_fps = {0, "cl_capturevideo_fps", "30", "how many frames per second to save (29.97 for NTSC, 30 for typical PC video, 15 can be useful)"};
cvar_t cl_capturevideo_number = {CVAR_SAVE, "cl_capturevideo_number", "1", "number to append to video filename, incremented each time a capture begins"};
cvar_t r_letterbox = {0, "r_letterbox", "0", "reduces vertical height of view to simulate a letterboxed movie effect (can be used by mods for cutscenes)"};
- cvar_t r_stereo_separation = {0, "r_stereo_separation", "4", "separation distance of eyes in the world (negative values are only useful for cross-eyed viewing)"};
cvar_t r_stereo_sidebyside = {0, "r_stereo_sidebyside", "0", "side by side views for those who can't afford glasses but can afford eye strain (note: use a negative r_stereo_separation if you want cross-eyed viewing)"};
cvar_t r_stereo_redblue = {0, "r_stereo_redblue", "0", "red/blue anaglyph stereo glasses (note: most of these glasses are actually red/cyan, try that one too)"};
cvar_t r_stereo_redcyan = {0, "r_stereo_redcyan", "0", "red/cyan anaglyph stereo glasses, the kind given away at drive-in movies like Creature From The Black Lagoon In 3D"};
cvar_t r_stereo_redgreen = {0, "r_stereo_redgreen", "0", "red/green anaglyph stereo glasses (for those who don't mind yellow)"};
cvar_t r_stereo_angle = {0, "r_stereo_angle", "0", "separation angle of eyes (makes the views look different directions, as an example, 90 gives a 90 degree separation where the views are 45 degrees left and 45 degrees right)"};
cvar_t scr_zoomwindow = {CVAR_SAVE, "scr_zoomwindow", "0", "displays a zoomed in overlay window"};
cvar_t scr_zoomwindow_viewsizex = {CVAR_SAVE, "scr_zoomwindow_viewsizex", "20", "horizontal viewsize of zoom window"};
cvar_t scr_zoomwindow_viewsizey = {CVAR_SAVE, "scr_zoomwindow_viewsizey", "20", "vertical viewsize of zoom window"};
--- 36,47 ----
cvar_t cl_capturevideo_fps = {0, "cl_capturevideo_fps", "30", "how many frames per second to save (29.97 for NTSC, 30 for typical PC video, 15 can be useful)"};
cvar_t cl_capturevideo_number = {CVAR_SAVE, "cl_capturevideo_number", "1", "number to append to video filename, incremented each time a capture begins"};
cvar_t r_letterbox = {0, "r_letterbox", "0", "reduces vertical height of view to simulate a letterboxed movie effect (can be used by mods for cutscenes)"};
cvar_t r_stereo_sidebyside = {0, "r_stereo_sidebyside", "0", "side by side views for those who can't afford glasses but can afford eye strain (note: use a negative r_stereo_separation if you want cross-eyed viewing)"};
cvar_t r_stereo_redblue = {0, "r_stereo_redblue", "0", "red/blue anaglyph stereo glasses (note: most of these glasses are actually red/cyan, try that one too)"};
cvar_t r_stereo_redcyan = {0, "r_stereo_redcyan", "0", "red/cyan anaglyph stereo glasses, the kind given away at drive-in movies like Creature From The Black Lagoon In 3D"};
cvar_t r_stereo_redgreen = {0, "r_stereo_redgreen", "0", "red/green anaglyph stereo glasses (for those who don't mind yellow)"};
cvar_t r_stereo_angle = {0, "r_stereo_angle", "0", "separation angle of eyes (makes the views look different directions, as an example, 90 gives a 90 degree separation where the views are 45 degrees left and 45 degrees right)"};
+ cvar_t r_stereo_convergence = {CVAR_SAVE, "r_stereo_convergence", "4", "adjust to bring the game out of screen more or less, no negative number please.)"};
cvar_t scr_zoomwindow = {CVAR_SAVE, "scr_zoomwindow", "0", "displays a zoomed in overlay window"};
cvar_t scr_zoomwindow_viewsizex = {CVAR_SAVE, "scr_zoomwindow_viewsizex", "20", "horizontal viewsize of zoom window"};
cvar_t scr_zoomwindow_viewsizey = {CVAR_SAVE, "scr_zoomwindow_viewsizey", "20", "vertical viewsize of zoom window"};
***************
*** 806,812 ****
Cvar_RegisterVariable (&cl_capturevideo_fps);
Cvar_RegisterVariable (&cl_capturevideo_number);
Cvar_RegisterVariable (&r_letterbox);
! Cvar_RegisterVariable(&r_stereo_separation);
Cvar_RegisterVariable(&r_stereo_sidebyside);
Cvar_RegisterVariable(&r_stereo_redblue);
Cvar_RegisterVariable(&r_stereo_redcyan);
--- 806,812 ----
Cvar_RegisterVariable (&cl_capturevideo_fps);
Cvar_RegisterVariable (&cl_capturevideo_number);
Cvar_RegisterVariable (&r_letterbox);
! Cvar_RegisterVariable(&r_stereo_convergence);
Cvar_RegisterVariable(&r_stereo_sidebyside);
Cvar_RegisterVariable(&r_stereo_redblue);
Cvar_RegisterVariable(&r_stereo_redcyan);
***************
*** 1898,1904 ****
void R_Shadow_EditLights_DrawSelectedLightProperties(void);
int r_stereo_side;
!
void SCR_DrawScreen (void)
{
R_Mesh_Start();
--- 1898,1904 ----
void R_Shadow_EditLights_DrawSelectedLightProperties(void);
int r_stereo_side;
! stereoframe_t stereo_frame;
void SCR_DrawScreen (void)
{
R_Mesh_Start();
***************
*** 2218,2234 ****
{
matrix4x4_t originalmatrix = r_refdef.view.matrix;
matrix4x4_t offsetmatrix;
! Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_separation.value * 0.5f, 0, 0, r_stereo_angle.value * 0.5f, 0, 1);
Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
if (r_stereo_sidebyside.integer)
r_stereo_side = 0;
if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
! r_refdef.view.colormask[0] = 1;
! r_refdef.view.colormask[1] = 0;
! r_refdef.view.colormask[2] = 0;
}
if (vid.stereobuffer)
--- 2218,2236 ----
{
matrix4x4_t originalmatrix = r_refdef.view.matrix;
matrix4x4_t offsetmatrix;
! Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_convergence.value * -0.5f, 0, 0, r_stereo_angle.value * 0.5f, 0, 1);
Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
+ stereo_frame = STEREO_RIGHT;
+
if (r_stereo_sidebyside.integer)
r_stereo_side = 0;
if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
! r_refdef.view.colormask[0] = 0;
! r_refdef.view.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
! r_refdef.view.colormask[2] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
}
if (vid.stereobuffer)
***************
*** 2236,2252 ****
SCR_DrawScreen();
! Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_separation.value * -0.5f, 0, 0, r_stereo_angle.value * -0.5f, 0, 1);
Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
if (r_stereo_sidebyside.integer)
r_stereo_side = 1;
if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
! r_refdef.view.colormask[0] = 0;
! r_refdef.view.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
! r_refdef.view.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
}
if (vid.stereobuffer)
--- 2238,2256 ----
SCR_DrawScreen();
! Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_convergence.value * 0.5f, 0, 0, r_stereo_angle.value * -0.5f, 0, 1);
Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
+ stereo_frame = STEREO_LEFT;
+
if (r_stereo_sidebyside.integer)
r_stereo_side = 1;
if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
! r_refdef.view.colormask[0] = r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer;
! r_refdef.view.colormask[1] = 0;
! r_refdef.view.colormask[2] = 0;
}
if (vid.stereobuffer)
*** MyDownloads/darkplaces/gl_backend.c 2008-05-07 03:25:00.000000000 -0400
--- darkplaces/gl_backend.c 2008-07-01 08:07:45.000000000 -0400
***************
*** 16,22 ****
cvar_t gl_lockarrays = {0, "gl_lockarrays", "0", "enables use of glLockArraysEXT, may cause glitches with some broken drivers, and may be slower than normal"};
cvar_t gl_lockarrays_minimumvertices = {0, "gl_lockarrays_minimumvertices", "1", "minimum number of vertices required for use of glLockArraysEXT, setting this too low may reduce performance"};
cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
!
cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
qboolean v_flipped_state = false;
--- 16,22 ----
cvar_t gl_lockarrays = {0, "gl_lockarrays", "0", "enables use of glLockArraysEXT, may cause glitches with some broken drivers, and may be slower than normal"};
cvar_t gl_lockarrays_minimumvertices = {0, "gl_lockarrays_minimumvertices", "1", "minimum number of vertices required for use of glLockArraysEXT, setting this too low may reduce performance"};
cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
! cvar_t r_stereo_separation = {0, "r_stereo_separation", "4", "separation distance of eyes in the world (negative values are only useful for cross-eyed viewing)"};
cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
qboolean v_flipped_state = false;
***************
*** 255,260 ****
--- 255,261 ----
Cvar_RegisterVariable(&gl_vbo);
Cvar_RegisterVariable(&gl_paranoid);
Cvar_RegisterVariable(&gl_printcheckerror);
+ Cvar_RegisterVariable(&r_stereo_separation);
#ifdef NORENDER
Cvar_SetValue("r_render", 0);
#endif
***************
*** 305,310 ****
--- 306,327 ----
R_Mesh_Matrix(&tempmatrix);
}
+ void Setup_StereoView_Frustum (double *leftx, double *rightx, double frustumx, double znear)
+ {
+ double novfcl;
+ novfcl = znear / (110 / frustumx );
+ if(stereo_frame == STEREO_LEFT)
+ {
+ *leftx = -frustumx * znear + r_stereo_separation.value * novfcl ;
+ *rightx = frustumx * znear + r_stereo_separation.value * novfcl ;
+ }
+ if(stereo_frame == STEREO_RIGHT)
+ {
+ *leftx = -frustumx * znear - r_stereo_separation.value * novfcl ;
+ *rightx = frustumx * znear - r_stereo_separation.value * novfcl ;
+ }
+ }
+
static void GL_BuildFrustum(double m[16], double left, double right, double bottom, double top, double nearVal, double farVal)
{
m[0] = 2 * nearVal / (right - left);
***************
*** 330,350 ****
void GL_SetupView_Mode_Perspective (double frustumx, double frustumy, double zNear, double zFar)
{
! double m[16];
// set up viewpoint
CHECKGLERROR
qglMatrixMode(GL_PROJECTION);CHECKGLERROR
// set view pyramid
#if 1
// avoid glGetDoublev whenever possible, it may stall the render pipeline
// in the tested cases (nvidia) no measurable fps difference, but it sure
// makes a difference over a network line with GLX
! GL_BuildFrustum(m, -frustumx * zNear, frustumx * zNear, -frustumy * zNear, frustumy * zNear, zNear, zFar);
qglLoadMatrixd(m);CHECKGLERROR
#else
qglLoadIdentity();CHECKGLERROR
! qglFrustum(-frustumx * zNear, frustumx * zNear, -frustumy * zNear, frustumy * zNear, zNear, zFar);CHECKGLERROR
qglGetDoublev(GL_PROJECTION_MATRIX, m);CHECKGLERROR
#endif
Matrix4x4_FromArrayDoubleGL(&backend_projectmatrix, m);
--- 347,388 ----
void GL_SetupView_Mode_Perspective (double frustumx, double frustumy, double zNear, double zFar)
{
! double m[16], left, right;
// set up viewpoint
CHECKGLERROR
qglMatrixMode(GL_PROJECTION);CHECKGLERROR
+
// set view pyramid
#if 1
// avoid glGetDoublev whenever possible, it may stall the render pipeline
// in the tested cases (nvidia) no measurable fps difference, but it sure
// makes a difference over a network line with GLX
!
! //assymetric viewing frustum for stereo mode
!
! if (stereo_frame)
! {
! Setup_StereoView_Frustum (&left, &right, frustumx, zNear);
! GL_BuildFrustum(m, left, right, -frustumy * zNear, frustumy * zNear, zNear, zFar);
! }
! else
! {
! GL_BuildFrustum(m, -frustumx * zNear, frustumx * zNear, -frustumy * zNear, frustumy * zNear, zNear, zFar);
! }
qglLoadMatrixd(m);CHECKGLERROR
#else
qglLoadIdentity();CHECKGLERROR
!
! if (stereo_frame)
! {
! Setup_StereoView_Frustum (&left, &right, frustumx, zNear);
! qglFrustum(left, right, -frustumy * zNear, frustumy * zNear, zNear, zFar);
! }
! else
! {
! qglFrustum(-frustumx * zNear, frustumx * zNear, -frustumy * zNear, frustumy * zNear, zNear, zFar);CHECKGLERROR
! }
qglGetDoublev(GL_PROJECTION_MATRIX, m);CHECKGLERROR
#endif
Matrix4x4_FromArrayDoubleGL(&backend_projectmatrix, m);
***************
*** 355,369 ****
void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double frustumx, double frustumy, double zNear)
{
! double nudge, m[16];
// set up viewpoint
CHECKGLERROR
qglMatrixMode(GL_PROJECTION);CHECKGLERROR
qglLoadIdentity();CHECKGLERROR
// set view pyramid
nudge = 1.0 - 1.0 / (1<<23);
! m[ 0] = 1.0 / frustumx;
m[ 1] = 0;
m[ 2] = 0;
m[ 3] = 0;
--- 393,422 ----
void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double frustumx, double frustumy, double zNear)
{
! double nudge, m[16], left, right;
// set up viewpoint
CHECKGLERROR
qglMatrixMode(GL_PROJECTION);CHECKGLERROR
qglLoadIdentity();CHECKGLERROR
+
+ //assymetric viewing frustum for stereo mode
+
+ if (stereo_frame)
+ {
+ Setup_StereoView_Frustum (&left, &right, frustumx, zNear);
+
+ m[ 0] = 2 * zNear / (right - left);
+ m[ 8] = ( right + left ) / (right - left);
+ } else {
+
+ m[ 0] = 1.0 / frustumx;
+ m[ 8] = 0;
+ }
+
// set view pyramid
nudge = 1.0 - 1.0 / (1<<23);
! // m[ 0] = 1.0 / frustumx;
m[ 1] = 0;
m[ 2] = 0;
m[ 3] = 0;
***************
*** 371,377 ****
m[ 5] = 1.0 / frustumy;
m[ 6] = 0;
m[ 7] = 0;
! m[ 8] = 0;
m[ 9] = 0;
m[10] = -nudge;
m[11] = -1;
--- 424,430 ----
m[ 5] = 1.0 / frustumy;
m[ 6] = 0;
m[ 7] = 0;
! // m[ 8] = 0;
m[ 9] = 0;
m[10] = -nudge;
m[11] = -1;
*** MyDownloads/darkplaces/quakedef.h 2008-02-04 07:47:04.000000000 -0500
--- darkplaces/quakedef.h 2008-06-30 11:03:34.000000000 -0400
***************
*** 347,352 ****
--- 347,362 ----
void Sys_Shared_Init(void);
+ typedef enum stereoframe_s
+ {
+ STEREO_CENTER,
+ STEREO_RIGHT,
+ STEREO_LEFT,
+ }
+ stereoframe_t;
+
+ extern stereoframe_t stereo_frame;
+
// Flag in size field of demos to indicate a client->server packet. Demo
// playback will ignore this, but it may be useful to make DP sniff packets to
// debug protocol exploits.