X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=gl_backend.c;h=7b21ec7ce386420ecbcc43fa877a00d3e89be9e1;hb=8677d9890acb9f0fcf1701d70f79fc9e3b69d6e1;hp=a4fd9fcb1f4f0439f9e42a4d2bcf694f69036435;hpb=452858bbdaf67f5e1a13486f0abb24baffe7ea20;p=xonotic%2Fdarkplaces.git diff --git a/gl_backend.c b/gl_backend.c index a4fd9fcb..7b21ec7c 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -2,6 +2,7 @@ #include "quakedef.h" #include "image.h" #include "jpeg.h" +#include "cl_collision.h" cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1"}; cvar_t gl_mesh_testarrayelement = {0, "gl_mesh_testarrayelement", "0"}; @@ -154,7 +155,7 @@ void GL_Backend_FreeArrays(void) static void gl_backend_start(void) { - Con_DPrintf("OpenGL Backend started\n"); + Con_DPrint("OpenGL Backend started\n"); if (qglDrawRangeElements != NULL) { CHECKGLERROR @@ -177,7 +178,7 @@ static void gl_backend_shutdown(void) backendunits = 0; backendactive = false; - Con_DPrintf("OpenGL Backend shutting down\n"); + Con_DPrint("OpenGL Backend shutting down\n"); GL_Backend_FreeArrays(); } @@ -186,6 +187,11 @@ static void gl_backend_newmap(void) { } +cvar_t scr_zoomwindow = {CVAR_SAVE, "scr_zoomwindow", "0"}; +cvar_t scr_zoomwindow_viewsizex = {CVAR_SAVE, "scr_zoomwindow_viewsizex", "20"}; +cvar_t scr_zoomwindow_viewsizey = {CVAR_SAVE, "scr_zoomwindow_viewsizey", "20"}; +cvar_t scr_zoomwindow_fov = {CVAR_SAVE, "scr_zoomwindow_fov", "20"}; + void gl_backend_init(void) { int i; @@ -210,17 +216,13 @@ void gl_backend_init(void) Cvar_RegisterVariable(&gl_mesh_drawrangeelements); Cvar_RegisterVariable(&gl_mesh_testarrayelement); Cvar_RegisterVariable(&gl_mesh_testmanualfeeding); - R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap); -} -void GL_SetupView_ViewPort (int x, int y, int width, int height) -{ - if (!r_render.integer) - return; + Cvar_RegisterVariable(&scr_zoomwindow); + Cvar_RegisterVariable(&scr_zoomwindow_viewsizex); + Cvar_RegisterVariable(&scr_zoomwindow_viewsizey); + Cvar_RegisterVariable(&scr_zoomwindow_fov); - // y is weird beause OpenGL is bottom to top, we use top to bottom - qglViewport(x, vid.realheight - (y + height), width, height); - CHECKGLERROR + R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap); } void GL_SetupView_Orientation_Identity (void) @@ -284,8 +286,8 @@ void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, dou m[ 7] = 0; m[ 8] = 0; m[ 9] = 0; - m[10] = -1 * nudge; - m[11] = -1 * nudge; + m[10] = -nudge; + m[11] = -1; m[12] = 0; m[13] = 0; m[14] = -2 * zNear * nudge; @@ -343,6 +345,7 @@ static struct int blendfunc2; int blend; GLboolean depthmask; + int colormask; // stored as bottom 4 bits: r g b a (3 2 1 0 order) int depthtest; int scissortest; int unit; @@ -425,6 +428,7 @@ void GL_Backend_ResetState(void) gl_state.blendfunc2 = GL_ZERO; gl_state.blend = false; gl_state.depthmask = GL_TRUE; + gl_state.colormask = 15; gl_state.color4f[0] = gl_state.color4f[1] = gl_state.color4f[2] = gl_state.color4f[3] = 1; gl_state.lockrange_first = 0; gl_state.lockrange_count = 0; @@ -433,6 +437,7 @@ void GL_Backend_ResetState(void) CHECKGLERROR + qglColorMask(1, 1, 1, 1); qglEnable(GL_CULL_FACE);CHECKGLERROR qglCullFace(GL_FRONT);CHECKGLERROR qglEnable(GL_DEPTH_TEST);CHECKGLERROR @@ -482,6 +487,8 @@ void GL_BlendFunc(int blendfunc1, int blendfunc2) { if (gl_state.blendfunc1 != blendfunc1 || gl_state.blendfunc2 != blendfunc2) { + if (r_showtrispass) + return; qglBlendFunc(gl_state.blendfunc1 = blendfunc1, gl_state.blendfunc2 = blendfunc2);CHECKGLERROR if (gl_state.blendfunc2 == GL_ZERO) { @@ -517,6 +524,8 @@ void GL_DepthMask(int state) { if (gl_state.depthmask != state) { + if (r_showtrispass) + return; qglDepthMask(gl_state.depthmask = state);CHECKGLERROR } } @@ -525,6 +534,8 @@ void GL_DepthTest(int state) { if (gl_state.depthtest != state) { + if (r_showtrispass) + return; gl_state.depthtest = state; if (gl_state.depthtest) { @@ -537,35 +548,15 @@ void GL_DepthTest(int state) } } -void GL_VertexPointer(const float *p) -{ - if (gl_state.pointer_vertex != p) - { - gl_state.pointer_vertex = p; - CHECKGLERROR - qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), gl_state.pointer_vertex); - CHECKGLERROR - } -} - -void GL_ColorPointer(const float *p) +void GL_ColorMask(int r, int g, int b, int a) { - if (gl_state.pointer_color != p) + int state = r*8 + g*4 + b*2 + a*1; + if (gl_state.colormask != state) { - CHECKGLERROR - if (!gl_state.pointer_color) - { - qglEnableClientState(GL_COLOR_ARRAY); - CHECKGLERROR - } - else if (!p) - { - qglDisableClientState(GL_COLOR_ARRAY); - CHECKGLERROR - } - gl_state.pointer_color = p; - qglColorPointer(4, GL_FLOAT, sizeof(float[4]), gl_state.pointer_color); - CHECKGLERROR + if (r_showtrispass) + return; + gl_state.colormask = state; + qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR } } @@ -573,17 +564,28 @@ void GL_Color(float cr, float cg, float cb, float ca) { if (gl_state.pointer_color || gl_state.color4f[0] != cr || gl_state.color4f[1] != cg || gl_state.color4f[2] != cb || gl_state.color4f[3] != ca) { - GL_ColorPointer(NULL); + if (r_showtrispass) + return; gl_state.color4f[0] = cr; gl_state.color4f[1] = cg; gl_state.color4f[2] = cb; gl_state.color4f[3] = ca; CHECKGLERROR - qglColor4f(cr, cg, cb, ca); + qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]); CHECKGLERROR } } +void GL_ShowTrisColor(float cr, float cg, float cb, float ca) +{ + if (!r_showtrispass) + return; + r_showtrispass = false; + GL_Color(cr * r_showtris.value, cg * r_showtris.value, cb * r_showtris.value, ca); + r_showtrispass = true; +} + + void GL_LockArrays(int first, int count) { if (gl_state.lockrange_count != count || gl_state.lockrange_first != first) @@ -595,7 +597,7 @@ void GL_LockArrays(int first, int count) qglUnlockArraysEXT(); CHECKGLERROR } - if (count && gl_supportslockarrays && gl_lockarrays.integer) + if (count && gl_supportslockarrays && gl_lockarrays.integer && r_render.integer) { gl_state.lockrange_first = first; gl_state.lockrange_count = count; @@ -626,6 +628,13 @@ void GL_ScissorTest(int state) CHECKGLERROR } +void GL_Clear(int mask) +{ + if (r_showtrispass) + return; + qglClear(mask);CHECKGLERROR +} + void GL_TransformToScreen(const vec4_t in, vec4_t out) { vec4_t temp; @@ -633,8 +642,8 @@ void GL_TransformToScreen(const vec4_t in, vec4_t out) Matrix4x4_Transform4 (&backend_viewmatrix, in, temp); Matrix4x4_Transform4 (&backend_projectmatrix, temp, out); iw = 1.0f / out[3]; - out[0] = r_refdef.x + (out[0] * iw + 1.0f) * r_refdef.width * 0.5f; - out[1] = r_refdef.y + (out[1] * iw + 1.0f) * r_refdef.height * 0.5f; + 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; } @@ -670,50 +679,54 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) Con_Printf("R_Mesh_Draw(%d, %d, %08p);\n", numverts, numtriangles, elements); return; } + CHECKGLERROR + if (r_showtrispass) + { + R_Mesh_Draw_ShowTris(numverts, numtriangles, elements); + return; + } c_meshs++; c_meshelements += numelements; - CHECKGLERROR - if (r_render.integer) + if (gl_paranoid.integer) { - if (gl_paranoid.integer) + int i, j, size; + const int *p; + if (!qglIsEnabled(GL_VERTEX_ARRAY)) + Con_Print("R_Mesh_Draw: vertex array not enabled\n"); + for (j = 0, size = numverts * (int)sizeof(float[3]), p = gl_state.pointer_vertex;j < size;j += sizeof(int), p++) + paranoidblah += *p; + if (gl_state.pointer_color) { - int i, j, size; - const int *p; - if (!qglIsEnabled(GL_VERTEX_ARRAY)) - Con_Printf("R_Mesh_Draw: vertex array not enabled\n"); - for (j = 0, size = numverts * (int)sizeof(float[3]), p = gl_state.pointer_vertex;j < size;j += sizeof(int), p++) + if (!qglIsEnabled(GL_COLOR_ARRAY)) + Con_Print("R_Mesh_Draw: color array set but not enabled\n"); + for (j = 0, size = numverts * (int)sizeof(float[4]), p = gl_state.pointer_color;j < size;j += sizeof(int), p++) paranoidblah += *p; - if (gl_state.pointer_color) + } + for (i = 0;i < backendunits;i++) + { + if (gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap || gl_state.units[i].arrayenabled) { - if (!qglIsEnabled(GL_COLOR_ARRAY)) - Con_Printf("R_Mesh_Draw: color array set but not enabled\n"); - for (j = 0, size = numverts * (int)sizeof(float[4]), p = gl_state.pointer_color;j < size;j += sizeof(int), p++) + if (gl_state.units[i].arrayenabled && !(gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap)) + Con_Print("R_Mesh_Draw: array enabled but no texture bound\n"); + GL_ActiveTexture(i); + if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY)) + Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n"); + for (j = 0, size = numverts * ((gl_state.units[i].t3d || gl_state.units[i].tcubemap) ? (int)sizeof(float[3]) : (int)sizeof(float[2])), p = gl_state.units[i].pointer_texcoord;j < size;j += sizeof(int), p++) paranoidblah += *p; } - for (i = 0;i < backendunits;i++) - { - if (gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap || gl_state.units[i].arrayenabled) - { - if (gl_state.units[i].arrayenabled && !(gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap)) - Con_Printf("R_Mesh_Draw: array enabled but no texture bound\n"); - GL_ActiveTexture(i); - if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY)) - Con_Printf("R_Mesh_Draw: texcoord array set but not enabled\n"); - for (j = 0, size = numverts * ((gl_state.units[i].t3d || gl_state.units[i].tcubemap) ? (int)sizeof(float[3]) : (int)sizeof(float[2])), p = gl_state.units[i].pointer_texcoord;j < size;j += sizeof(int), p++) - paranoidblah += *p; - } - } - for (i = 0;i < numtriangles * 3;i++) + } + for (i = 0;i < numtriangles * 3;i++) + { + if (elements[i] < 0 || elements[i] >= numverts) { - if (elements[i] < 0 || elements[i] >= numverts) - { - Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range 0 - %i) in elements list\n", elements[i], numverts); - return; - } + Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range 0 - %i) in elements list\n", elements[i], numverts); + return; } } CHECKGLERROR - GL_LockArrays(0, numverts); + } + if (r_render.integer) + { CHECKGLERROR if (gl_mesh_testmanualfeeding.integer) { @@ -785,8 +798,6 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR } CHECKGLERROR - GL_LockArrays(0, 0); - CHECKGLERROR } } @@ -795,9 +806,9 @@ void R_Mesh_Finish(void) { int i; BACKENDACTIVECHECK - CHECKGLERROR + CHECKGLERROR GL_LockArrays(0, 0); - CHECKGLERROR + CHECKGLERROR for (i = backendunits - 1;i >= 0;i--) { @@ -857,13 +868,45 @@ void R_Mesh_TextureMatrix(int unitnumber, const matrix4x4_t *matrix) } } -void R_Mesh_State_Texture(const rmeshstate_t *m) +void R_Mesh_State(const rmeshstate_t *m) { int i, combinergb, combinealpha, scale, arrayis3d; gltextureunit_t *unit; BACKENDACTIVECHECK + if (gl_state.pointer_vertex != m->pointer_vertex) + { + gl_state.pointer_vertex = m->pointer_vertex; + CHECKGLERROR + qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), gl_state.pointer_vertex); + CHECKGLERROR + } + + if (r_showtrispass) + return; + + if (gl_state.pointer_color != m->pointer_color) + { + CHECKGLERROR + if (!gl_state.pointer_color) + { + qglEnableClientState(GL_COLOR_ARRAY); + CHECKGLERROR + } + else if (!m->pointer_color) + { + qglDisableClientState(GL_COLOR_ARRAY); + CHECKGLERROR + // when color array is on the glColor gets trashed, set it again + qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]); + CHECKGLERROR + } + gl_state.pointer_color = m->pointer_color; + qglColorPointer(4, GL_FLOAT, sizeof(float[4]), gl_state.pointer_color); + CHECKGLERROR + } + if (gl_backend_rebindtextures) { gl_backend_rebindtextures = false; @@ -939,7 +982,7 @@ void R_Mesh_State_Texture(const rmeshstate_t *m) { GL_ActiveTexture(i); unit->combinergb = combinergb; - if (gl_combine.integer) + if (gl_combine.integer) { qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR } @@ -1003,7 +1046,7 @@ void R_Mesh_State_Texture(const rmeshstate_t *m) } } -void R_Mesh_Draw_ShowTris(int numverts, int numtriangles, int *elements) +void R_Mesh_Draw_ShowTris(int numverts, int numtriangles, const int *elements) { qglBegin(GL_LINES); for (;numtriangles;numtriangles--, elements += 3) @@ -1062,7 +1105,7 @@ void R_ClearScreen(void) qglClearStencil(128);CHECKGLERROR } // clear the screen - qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));CHECKGLERROR + GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0)); // set dithering mode if (gl_dither.integer) { @@ -1075,6 +1118,17 @@ void R_ClearScreen(void) } } +/* +==================== +CalcFov +==================== +*/ +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; +} + /* ================== SCR_UpdateScreen @@ -1087,11 +1141,14 @@ void SCR_UpdateScreen (void) { if (gl_delayfinish.integer) { - VID_Finish (); - + 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) @@ -1100,6 +1157,7 @@ void SCR_UpdateScreen (void) if (gl_combine.integer && (!gl_combine_extension || r_textureunits.integer < 2)) Cvar_SetValueQuick(&gl_combine, 0); +showtris: R_TimeReport("setup"); R_ClearScreen(); @@ -1107,11 +1165,95 @@ void SCR_UpdateScreen (void) R_TimeReport("clear"); if (scr_conlines < vid.conheight && cls.signon == SIGNONS) + { + 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; + } + else + { + 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.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); + + if (cl.worldmodel) + { + Mod_CheckLoaded(cl.worldmodel); + contents = CL_PointSuperContents(r_vieworigin); + if (contents & SUPERCONTENTS_LIQUIDSMASK) + { + r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985); + r_refdef.fov_y *= (sin(cl.time * 3.0) * 0.015 + 0.985); + } + } + 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.fov_y = CalcFov(r_refdef.fov_x, r_refdef.width, r_refdef.height); + + R_RenderView(); + } + } + // draw 2D stuff R_DrawQueue(); + 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; + } + if (gl_delayfinish.integer) { // tell driver to commit it's partially full geometry queue to the rendering queue @@ -1120,8 +1262,9 @@ void SCR_UpdateScreen (void) } else { - VID_Finish (); - + R_Mesh_Finish(); + R_TimeReport("meshfinish"); + VID_Finish(); R_TimeReport("finish"); } } @@ -1358,13 +1501,13 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r) l->prev = l->next->prev; while (l->next->data && l->data && l->next->data->offset <= d->offset) { - //Con_Printf(">\n"); + //Con_Print(">\n"); l->next = l->next->next; l->prev = l->prev->next; } while (l->prev->data && l->data && l->prev->data->offset >= d->offset) { - //Con_Printf("<\n"); + //Con_Print("<\n"); l->prev = l->prev->prev; l->next = l->next->prev; }