cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1"};
cvar_t gl_mesh_testarrayelement = {0, "gl_mesh_testarrayelement", "0"};
cvar_t gl_mesh_testmanualfeeding = {0, "gl_mesh_testmanualfeeding", "0"};
-cvar_t gl_delayfinish = {CVAR_SAVE, "gl_delayfinish", "0"};
cvar_t gl_paranoid = {0, "gl_paranoid", "0"};
cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0"};
+cvar_t r_stereo_separation = {0, "r_stereo_separation", "4"};
+cvar_t r_stereo_sidebyside = {0, "r_stereo_sidebyside", "0"};
+cvar_t r_stereo_redblue = {0, "r_stereo_redblue", "0"};
+cvar_t r_stereo_redcyan = {0, "r_stereo_redcyan", "0"};
+cvar_t r_stereo_redgreen = {0, "r_stereo_redgreen", "0"};
cvar_t r_render = {0, "r_render", "1"};
cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1"};
void GL_Backend_AllocArrays(void)
{
if (!gl_backend_mempool)
- gl_backend_mempool = Mem_AllocPool("GL_Backend");
+ gl_backend_mempool = Mem_AllocPool("GL_Backend", 0, NULL);
R_Mesh_CacheArray_Startup();
}
Cvar_RegisterVariable(&r_render);
Cvar_RegisterVariable(&r_waterwarp);
+ Cvar_RegisterVariable(&r_stereo_separation);
+ Cvar_RegisterVariable(&r_stereo_sidebyside);
+ Cvar_RegisterVariable(&r_stereo_redblue);
+ Cvar_RegisterVariable(&r_stereo_redcyan);
+ Cvar_RegisterVariable(&r_stereo_redgreen);
Cvar_RegisterVariable(&gl_polyblend);
Cvar_RegisterVariable(&gl_dither);
Cvar_RegisterVariable(&gl_lockarrays);
- Cvar_RegisterVariable(&gl_delayfinish);
Cvar_RegisterVariable(&gl_paranoid);
Cvar_RegisterVariable(&gl_printcheckerror);
#ifdef NORENDER
iw = 1.0f / out[3];
out[0] = r_view_x + (out[0] * iw + 1.0f) * r_view_width * 0.5f;
out[1] = r_view_y + (out[1] * iw + 1.0f) * r_view_height * 0.5f;
- out[2] = out[2] * iw;
+ out[2] = r_view_z + (out[2] * iw + 1.0f) * r_view_depth * 0.5f;
}
// called at beginning of frame
float CalcFov (float fov_x, float width, float height)
{
// calculate vision size and alter by aspect, then convert back to angle
- return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
+ return atan (((height/width)/vid_pixelaspect.value)*tan(fov_x/360.0*M_PI))*360.0/M_PI;
+}
+
+int r_stereo_side;
+
+void SCR_DrawScreen (void)
+{
+ for (r_showtrispass = 0;r_showtrispass <= (r_showtris.value > 0);r_showtrispass++)
+ {
+ R_Mesh_Start();
+
+ R_TimeReport("setup");
+
+ if (r_showtrispass)
+ {
+ rmeshstate_t m;
+ r_showtrispass = 0;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthTest(GL_FALSE);
+ GL_DepthMask(GL_FALSE);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State(&m);
+ GL_ShowTrisColor(0.2,0.2,0.2,1);
+ r_showtrispass = 1;
+ }
+
+ if (scr_conlines < vid.conheight && cls.signon == SIGNONS)
+ {
+ float size;
+
+ size = scr_viewsize.value * (1.0 / 100.0);
+ size = min(size, 1);
+
+ if (r_stereo_sidebyside.integer)
+ {
+ r_refdef.width = vid.realwidth * size / 2.5;
+ r_refdef.height = vid.realheight * size / 2.5 * (1 - bound(0, r_letterbox.value, 100) / 100);
+ r_refdef.x = (vid.realwidth - r_refdef.width * 2.5) * 0.5;
+ r_refdef.y = (vid.realheight - r_refdef.height)/2;
+ if (r_stereo_side)
+ r_refdef.x += r_refdef.width * 1.5;
+ }
+ else
+ {
+ r_refdef.width = vid.realwidth * size;
+ r_refdef.height = vid.realheight * size * (1 - bound(0, r_letterbox.value, 100) / 100);
+ r_refdef.x = (vid.realwidth - r_refdef.width)/2;
+ r_refdef.y = (vid.realheight - r_refdef.height)/2;
+ }
+
+ // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
+ r_refdef.fov_x = scr_fov.value * cl.viewzoom * r_refdef.fovscale_x;
+ r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height) * r_refdef.fovscale_y;
+
+ R_RenderView();
+
+ if (scr_zoomwindow.integer)
+ {
+ float sizex = bound(10, scr_zoomwindow_viewsizex.value, 100) / 100.0;
+ float sizey = bound(10, scr_zoomwindow_viewsizey.value, 100) / 100.0;
+ r_refdef.width = vid.realwidth * sizex;
+ r_refdef.height = vid.realheight * sizey;
+ r_refdef.x = (vid.realwidth - r_refdef.width)/2;
+ r_refdef.y = 0;
+ r_refdef.fov_x = scr_zoomwindow_fov.value * r_refdef.fovscale_x;
+ r_refdef.fov_y = CalcFov(r_refdef.fov_x, r_refdef.width, r_refdef.height) * r_refdef.fovscale_y;
+
+ R_RenderView();
+ }
+ }
+
+ if (!r_stereo_sidebyside.integer)
+ {
+ r_refdef.width = vid.realwidth;
+ r_refdef.height = vid.realheight;
+ r_refdef.x = 0;
+ r_refdef.y = 0;
+ }
+
+ // draw 2D stuff
+ R_DrawQueue();
+
+ R_Mesh_Finish();
+
+ R_TimeReport("meshfinish");
+ }
}
/*
*/
void SCR_UpdateScreen (void)
{
- if (gl_delayfinish.integer)
- {
- R_Mesh_Finish();
- R_TimeReport("meshfinish");
- VID_Finish();
- R_TimeReport("finish");
- }
-
- R_Mesh_Start();
-
if (r_textureunits.integer > gl_textureunits)
Cvar_SetValueQuick(&r_textureunits, gl_textureunits);
if (r_textureunits.integer < 1)
if (gl_combine.integer && (!gl_combine_extension || r_textureunits.integer < 2))
Cvar_SetValueQuick(&gl_combine, 0);
-showtris:
- R_TimeReport("setup");
-
- R_ClearScreen();
-
- R_TimeReport("clear");
+ // don't allow cheats in multiplayer
+ if (!cl.islocalgame && cl.worldmodel)
+ {
+ if (r_fullbright.integer != 0)
+ Cvar_Set ("r_fullbright", "0");
+ if (r_ambient.value != 0)
+ Cvar_Set ("r_ambient", "0");
+ }
- if (scr_conlines < vid.conheight && cls.signon == SIGNONS)
+ // bound viewsize
+ if (scr_viewsize.value < 30)
+ Cvar_Set ("viewsize","30");
+ if (scr_viewsize.value > 120)
+ Cvar_Set ("viewsize","120");
+
+ // bound field of view
+ if (scr_fov.value < 1)
+ Cvar_Set ("fov","1");
+ if (scr_fov.value > 170)
+ Cvar_Set ("fov","170");
+
+ // intermission is always full screen
+ if (cl.intermission)
+ sb_lines = 0;
+ else
{
- float size;
- int contents;
-
- // bound viewsize
- if (scr_viewsize.value < 30)
- Cvar_Set ("viewsize","30");
- if (scr_viewsize.value > 120)
- Cvar_Set ("viewsize","120");
-
- // bound field of view
- if (scr_fov.value < 1)
- Cvar_Set ("fov","1");
- if (scr_fov.value > 170)
- Cvar_Set ("fov","170");
-
- // intermission is always full screen
- if (cl.intermission)
- {
- size = 1;
- sb_lines = 0;
- }
+ if (scr_viewsize.value >= 120)
+ sb_lines = 0; // no status bar at all
+ else if (scr_viewsize.value >= 110)
+ sb_lines = 24; // no inventory
else
+ sb_lines = 24+16+8;
+ }
+
+ r_refdef.fovscale_x = 1;
+ r_refdef.fovscale_y = 1;
+ if (r_waterwarp.value > 0 && cl.worldmodel)
+ {
+ Mod_CheckLoaded(cl.worldmodel);
+ if (CL_PointSuperContents(r_vieworigin) & SUPERCONTENTS_LIQUIDSMASK)
{
- if (scr_viewsize.value >= 120)
- sb_lines = 0; // no status bar at all
- else if (scr_viewsize.value >= 110)
- sb_lines = 24; // no inventory
- else
- sb_lines = 24+16+8;
- size = scr_viewsize.value * (1.0 / 100.0);
- size = min(size, 1);
+ r_refdef.fovscale_x = 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
+ r_refdef.fovscale_y = 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
-
- r_refdef.width = vid.realwidth * size;
- r_refdef.height = vid.realheight * size;
- r_refdef.x = (vid.realwidth - r_refdef.width)/2;
- r_refdef.y = (vid.realheight - r_refdef.height)/2;
-
- // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
- r_refdef.fov_x = scr_fov.value * cl.viewzoom;
- r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
+ }
+
+ r_refdef.colormask[0] = 1;
+ r_refdef.colormask[1] = 1;
+ r_refdef.colormask[2] = 1;
+
+ CHECKGLERROR
+ qglViewport(0, 0, vid.realwidth, vid.realheight);
+ qglDisable(GL_SCISSOR_TEST);
+ qglDepthMask(1);
+ qglColorMask(1,1,1,1);
+ qglClearColor(0,0,0,0);
+ qglClear(GL_COLOR_BUFFER_BIT);
+ CHECKGLERROR
- if (r_waterwarp.value > 0)
+ R_TimeReport("clear");
+
+ if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer || r_stereo_sidebyside.integer)
+ {
+ matrix4x4_t originalmatrix = r_refdef.viewentitymatrix;
+ r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[0][1];
+ r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[1][1];
+ r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * -0.5f * r_refdef.viewentitymatrix.m[2][1];
+
+ if (r_stereo_sidebyside.integer)
+ r_stereo_side = 0;
+
+ if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
- if (cl.worldmodel)
- {
- Mod_CheckLoaded(cl.worldmodel);
- contents = CL_PointSuperContents(r_vieworigin);
- if (contents & SUPERCONTENTS_LIQUIDSMASK)
- {
- r_refdef.fov_x *= 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
- r_refdef.fov_y *= 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
- }
- }
+ r_refdef.colormask[0] = 1;
+ r_refdef.colormask[1] = 0;
+ r_refdef.colormask[2] = 0;
}
- R_RenderView();
+ SCR_DrawScreen();
- if (scr_zoomwindow.integer)
- {
- float sizex = bound(10, scr_zoomwindow_viewsizex.value, 100) / 100.0;
- float sizey = bound(10, scr_zoomwindow_viewsizey.value, 100) / 100.0;
- r_refdef.width = vid.realwidth * sizex;
- r_refdef.height = vid.realheight * sizey;
- r_refdef.x = (vid.realwidth - r_refdef.width)/2;
- r_refdef.y = 0;
- r_refdef.fov_x = scr_zoomwindow_fov.value;
- r_refdef.fov_y = CalcFov(r_refdef.fov_x, r_refdef.width, r_refdef.height);
+ r_refdef.viewentitymatrix.m[0][3] = originalmatrix.m[0][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[0][1];
+ r_refdef.viewentitymatrix.m[1][3] = originalmatrix.m[1][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[1][1];
+ r_refdef.viewentitymatrix.m[2][3] = originalmatrix.m[2][3] + r_stereo_separation.value * 0.5f * r_refdef.viewentitymatrix.m[2][1];
- R_RenderView();
- }
- }
+ if (r_stereo_sidebyside.integer)
+ r_stereo_side = 1;
- // draw 2D stuff
- R_DrawQueue();
+ if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
+ {
+ r_refdef.colormask[0] = 0;
+ r_refdef.colormask[1] = r_stereo_redcyan.integer || r_stereo_redgreen.integer;
+ r_refdef.colormask[2] = r_stereo_redcyan.integer || r_stereo_redblue.integer;
+ }
- if (r_showtrispass)
- r_showtrispass = false;
- else if (r_showtris.value > 0)
- {
- rmeshstate_t m;
- GL_BlendFunc(GL_ONE, GL_ONE);
- GL_DepthTest(GL_FALSE);
- GL_DepthMask(GL_FALSE);
- memset(&m, 0, sizeof(m));
- R_Mesh_State(&m);
- r_showtrispass = true;
- GL_ShowTrisColor(0.2,0.2,0.2,1);
- goto showtris;
- }
+ SCR_DrawScreen();
- if (gl_delayfinish.integer)
- {
- // tell driver to commit it's partially full geometry queue to the rendering queue
- // (this doesn't wait for the commands themselves to complete)
- qglFlush();
+ r_refdef.viewentitymatrix = originalmatrix;
}
else
{
- R_Mesh_Finish();
- R_TimeReport("meshfinish");
- VID_Finish();
- R_TimeReport("finish");
+ r_showtrispass = false;
+ SCR_DrawScreen();
+
+ if (r_showtris.value > 0)
+ {
+ rmeshstate_t m;
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ GL_DepthTest(GL_FALSE);
+ GL_DepthMask(GL_FALSE);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State(&m);
+ r_showtrispass = true;
+ GL_ShowTrisColor(0.2,0.2,0.2,1);
+ SCR_DrawScreen();
+ r_showtrispass = false;
+ }
}
+
+ VID_Finish();
+ R_TimeReport("finish");
}
// dynamic vertex array buffer subsystem
//===========================================================================
+// FIXME: someday this should be dynamically allocated and resized?
float varray_vertex3f[65536*3];
+float varray_svector3f[65536*3];
+float varray_tvector3f[65536*3];
+float varray_normal3f[65536*3];
float varray_color4f[65536*4];
float varray_texcoord2f[4][65536*2];
float varray_texcoord3f[4][65536*3];
-float varray_normal3f[65536*3];
int earray_element3i[65536];
+float varray_vertex3f2[65536*3];
//===========================================================================
// vertex array caching subsystem