From 9d6f77621de650ffaaecb65a3485d51378632925 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 15 Apr 2018 23:17:19 +0000 Subject: [PATCH] Changed how polygonbegin guesses if the geometry is 2D or 3D, it now uses a separate variable rather than relying on r_refdef.draw2dstage. Reworked DrawQ_* and R_RenderView code to make clear distinctions between 2D and 3D code, this removes a lot of unnecessary calls to DrawQ_FlushUI (including ones that happened in R_RenderView). Added R_DebugLine which takes a line in world coordinates and adds it as a 2D line in CL_Mesh_UI. Added r_showparticleedges and r_showspriteedges debugging cvars which make use of R_DebugLine. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12397 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_particles.c | 7 ++++++ cl_screen.c | 4 ++++ clvm_cmds.c | 20 +++++++++++++++-- csprogs.c | 2 ++ draw.h | 16 ++++++++------ gl_draw.c | 17 +++------------ gl_rmain.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++---- mvm_cmds.c | 2 ++ progsvm.h | 7 ++++++ prvm_cmds.c | 30 +++++++++++++++++++++++++ r_sprites.c | 4 ++++ render.h | 3 +++ 12 files changed, 144 insertions(+), 27 deletions(-) diff --git a/cl_particles.c b/cl_particles.c index 4247755d..bf3c1d16 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -2862,6 +2862,13 @@ static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const t2f[6] = v[1];t2f[7] = tex->t1; break; } + if (r_showparticleedges.integer) + { + R_DebugLine(v3f, v3f + 3); + R_DebugLine(v3f + 3, v3f + 6); + R_DebugLine(v3f + 6, v3f + 9); + R_DebugLine(v3f + 9, v3f); + } } // now render batches of particles based on blendmode and texture diff --git a/cl_screen.c b/cl_screen.c index afdeab60..92137842 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -2077,6 +2077,10 @@ static void SCR_DrawScreen (void) R_UpdateVariables(); + // this will be set back to 0 by R_RenderView during CL_VM_UpdateView + r_refdef.draw2dstage = 1; + R_ResetViewRendering2D_Common(0, NULL, NULL, 0, 0, vid.width, vid.height, vid_conwidth.integer, vid_conheight.integer); + // Quake uses clockwise winding, so these are swapped r_refdef.view.cullface_front = GL_BACK; r_refdef.view.cullface_back = GL_FRONT; diff --git a/clvm_cmds.c b/clvm_cmds.c index 5ee778f9..e218878e 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -736,6 +736,8 @@ static void VM_CL_R_ClearScene (prvm_prog_t *prog) r_refdef.scene.numlights = 0; // restore the view settings to the values that VM_CL_UpdateView received from the client code r_refdef.view = csqc_original_r_refdef_view; + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = false; VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin); VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles); cl.csqc_vidvars.drawworld = r_drawworld.integer != 0; @@ -3278,6 +3280,9 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog) t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0; prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t; + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = false; + // update the views if (ismain) { @@ -3299,8 +3304,17 @@ static void VM_CL_R_PolygonBegin (prvm_prog_t *prog) texname = PRVM_G_STRING(OFS_PARM0); drawflags = (int)PRVM_G_FLOAT(OFS_PARM1); - // weird hacky way to figure out if this is a 2D HUD polygon or a scene polygon - draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage); + if (prog->argc >= 3) + draw2d = PRVM_G_FLOAT(OFS_PARM2) != 0; + else + { + // weird hacky way to figure out if this is a 2D HUD polygon or a scene + // polygon, for compatibility with mods aimed at old darkplaces versions + // - polygonbegin_guess2d is 0 if the most recent major call was + // clearscene, 1 if the most recent major call was drawpic (and similar) + // or renderscene + draw2d = prog->polygonbegin_guess2d; + } // we need to remember whether this is a 2D or 3D mesh we're adding to mod = draw2d ? CL_Mesh_UI() : CL_Mesh_CSQC(); @@ -4756,6 +4770,7 @@ void CLVM_init_cmd(prvm_prog_t *prog) { VM_Cmd_Init(prog); prog->polygonbegin_model = NULL; + prog->polygonbegin_guess2d = 0; } void CLVM_reset_cmd(prvm_prog_t *prog) @@ -4763,4 +4778,5 @@ void CLVM_reset_cmd(prvm_prog_t *prog) World_End(&cl.world); VM_Cmd_Reset(prog); prog->polygonbegin_model = NULL; + prog->polygonbegin_guess2d = 0; } diff --git a/csprogs.c b/csprogs.c index f0a01a26..6c2d1eff 100644 --- a/csprogs.c +++ b/csprogs.c @@ -486,6 +486,8 @@ qboolean CL_VM_UpdateView (double frametime) // CSQC_UpdateView function does not call R_ClearScene as it should r_refdef.scene.numentities = 0; r_refdef.scene.numlights = 0; + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = false; // pass in width and height as parameters (EXT_CSQC_1) PRVM_G_FLOAT(OFS_PARM0) = vid.width; PRVM_G_FLOAT(OFS_PARM1) = vid.height; diff --git a/draw.h b/draw.h index bbd964ed..3857e98e 100644 --- a/draw.h +++ b/draw.h @@ -134,7 +134,15 @@ extern dp_fonts_t dp_fonts; #define STRING_COLOR_RGB_TAG_CHAR 'x' #define STRING_COLOR_RGB_TAG "^x" -// all of these functions will set r_defdef.draw2dstage if not in 2D rendering mode (and of course prepare for 2D rendering in that case) +// prepare for 2D rendering (sets r_refdef.draw2dstage = 1 and calls R_ResetViewRendering2D) +void DrawQ_Start(void); +// resets r_refdef.draw2dstage to 0 +void DrawQ_Finish(void); +// batch draw the pending geometry in the CL_Mesh_UI() model and reset the model, +// to be called by things like DrawQ_SetClipArea which make disruptive state changes. +void DrawQ_FlushUI(void); +// use this when changing r_refdef.view.* from e.g. csqc +void DrawQ_RecalcView(void); // draw an image (or a filled rectangle if pic == NULL) void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags); @@ -163,12 +171,6 @@ void DrawQ_SetClipArea(float x, float y, float width, float height); void DrawQ_ResetClipArea(void); // draw a line void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags); -// resets r_refdef.draw2dstage -void DrawQ_Finish(void); -void DrawQ_RecalcView(void); // use this when changing r_refdef.view.* from e.g. csqc -// batch draw the pending geometry in the CL_Mesh_UI() model and reset the model, -// to be called by things like DrawQ_SetClipArea which make disruptive state changes. -void DrawQ_FlushUI(void); const char *Draw_GetPicName(cachepic_t *pic); int Draw_GetPicWidth(cachepic_t *pic); diff --git a/gl_draw.c b/gl_draw.c index 4f700ff7..ac92aa5d 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -744,11 +744,8 @@ void GL_Draw_Init (void) R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap, NULL, NULL); } -static void _DrawQ_Setup(void) // see R_ResetViewRendering2D +void DrawQ_Start(void) { - if (r_refdef.draw2dstage == 1) - return; - DrawQ_FlushUI(); r_refdef.draw2dstage = 1; R_ResetViewRendering2D_Common(0, NULL, NULL, 0, 0, vid.width, vid.height, vid_conwidth.integer, vid_conheight.integer); } @@ -760,7 +757,6 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); if (!pic) pic = Draw_CachePic("white"); if (width == 0) @@ -787,7 +783,6 @@ void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); if (!pic) pic = Draw_CachePic("white"); if (width == 0) @@ -1077,8 +1072,6 @@ float DrawQ_String_Scale(float startx, float starty, const char *text, size_t ma tw = Draw_GetPicWidth(fnt->pic); th = Draw_GetPicHeight(fnt->pic); - _DrawQ_Setup(); - if (!h) h = w; if (!h) { h = w = 1; @@ -1384,7 +1377,6 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height dp_model_t *mod = CL_Mesh_UI(); msurface_t *surf; int e0, e1, e2, e3; - _DrawQ_Setup(); if (!pic) pic = Draw_CachePic("white"); if (width == 0) @@ -1406,16 +1398,15 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f msurface_t *surf; int e0, e1, e2, e3; float offsetx, offsety; - _DrawQ_Setup(); // width is measured in real pixels if (fabs(x2 - x1) > fabs(y2 - y1)) { offsetx = 0; - offsety = width * vid_conheight.value / vid.height; + offsety = 0.5f * width * vid_conheight.value / vid.height; } else { - offsetx = width * vid_conwidth.value / vid.width; + offsetx = 0.5f * width * vid_conwidth.value / vid.width; offsety = 0; } surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_VERTEXCOLOR), true); @@ -1430,7 +1421,6 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f void DrawQ_SetClipArea(float x, float y, float width, float height) { int ix, iy, iw, ih; - _DrawQ_Setup(); DrawQ_FlushUI(); // We have to convert the con coords into real coords @@ -1466,7 +1456,6 @@ void DrawQ_SetClipArea(float x, float y, float width, float height) void DrawQ_ResetClipArea(void) { DrawQ_FlushUI(); - _DrawQ_Setup(); GL_ScissorTest(false); } diff --git a/gl_rmain.c b/gl_rmain.c index 5eaff437..1cfb0353 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -103,6 +103,8 @@ cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collis cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"}; cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"}; cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"}; +cvar_t r_showspriteedges = {0, "r_showspriteedges", "0", "renders a debug outline to show the polygon shape of each sprite frame rendered (may be 2 or more in case of interpolated animations), for debugging rendering bugs with specific view types"}; +cvar_t r_showparticleedges = {0, "r_showparticleedges", "0", "renders a debug outline to show the polygon shape of each particle, for debugging rendering bugs with specific view types"}; cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"}; cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"}; cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"}; @@ -4259,6 +4261,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor); Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset); Cvar_RegisterVariable(&r_showdisabledepthtest); + Cvar_RegisterVariable(&r_showspriteedges); + Cvar_RegisterVariable(&r_showparticleedges); Cvar_RegisterVariable(&r_drawportals); Cvar_RegisterVariable(&r_drawentities); Cvar_RegisterVariable(&r_draw2d); @@ -5684,15 +5688,11 @@ void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rt void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { - DrawQ_Finish(); - R_ResetViewRendering2D_Common(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight, 1.0f, 1.0f); } void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { - DrawQ_Finish(); - R_SetupView(true, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); GL_Color(1, 1, 1, 1); @@ -6930,6 +6930,9 @@ void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, i rtexture_t *viewcolortexture = NULL; int viewx = r_refdef.view.x, viewy = r_refdef.view.y, viewwidth = r_refdef.view.width, viewheight = r_refdef.view.height; + // finish any 2D rendering that was queued + DrawQ_Finish(); + dpsoftrast_test = r_test.integer; if (r_timereport_active) @@ -7067,6 +7070,9 @@ void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, i r_refdef.view.matrix = originalmatrix; CHECKGLERROR + + // go back to 2d rendering + DrawQ_Start(); } void R_RenderWaterPlanes(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) @@ -12321,6 +12327,51 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } +void R_DebugLine(vec3_t start, vec3_t end) +{ + dp_model_t *mod = CL_Mesh_UI(); + msurface_t *surf; + int e0, e1, e2, e3; + float offsetx, offsety, x1, y1, x2, y2, width = 1.0f; + float r1 = 1.0f, g1 = 0.0f, b1 = 0.0f, alpha1 = 0.25f; + float r2 = 1.0f, g2 = 1.0f, b2 = 0.0f, alpha2 = 0.25f; + vec4_t w[2], s[2]; + + // transform to screen coords first + Vector4Set(w[0], start[0], start[1], start[2], 1); + Vector4Set(w[1], end[0], end[1], end[2], 1); + R_Viewport_TransformToScreen(&r_refdef.view.viewport, w[0], s[0]); + R_Viewport_TransformToScreen(&r_refdef.view.viewport, w[1], s[1]); + x1 = s[0][0] * vid_conwidth.value / vid.width; + y1 = (vid.height - s[0][1]) * vid_conheight.value / vid.height; + x2 = s[1][0] * vid_conwidth.value / vid.width; + y2 = (vid.height - s[1][1]) * vid_conheight.value / vid.height; + //Con_DPrintf("R_DebugLine: %.0f,%.0f to %.0f,%.0f\n", x1, y1, x2, y2); + + // add the line to the UI mesh for drawing later + + // width is measured in real pixels + if (fabs(x2 - x1) > fabs(y2 - y1)) + { + offsetx = 0; + offsety = 0.5f * width * vid_conheight.value / vid.height; + } + else + { + offsetx = 0.5f * width * vid_conwidth.value / vid.width; + offsety = 0; + } + surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_VERTEXCOLOR), true); + e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r1, g1, b1, alpha1); + e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2); + e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2); + e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r1, g1, b1, alpha1); + Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2); + Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3); + +} + + void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass) { int q; diff --git a/mvm_cmds.c b/mvm_cmds.c index cc5d9c9f..00759e09 100644 --- a/mvm_cmds.c +++ b/mvm_cmds.c @@ -1613,6 +1613,7 @@ void MVM_init_cmd(prvm_prog_t *prog) VM_Cmd_Init(prog); prog->polygonbegin_model = NULL; + prog->polygonbegin_guess2d = 0; scene = R_GetScenePointer( RST_MENU ); @@ -1635,4 +1636,5 @@ void MVM_reset_cmd(prvm_prog_t *prog) //VM_Cmd_Init(); VM_Cmd_Reset(prog); prog->polygonbegin_model = NULL; + prog->polygonbegin_guess2d = 0; } diff --git a/progsvm.h b/progsvm.h index 4188a8fa..6bcb808a 100644 --- a/progsvm.h +++ b/progsvm.h @@ -601,6 +601,13 @@ typedef struct prvm_prog_s // stateful, so this tracks the last polygonbegin's choice of // CL_Mesh_CSQC or CL_Mesh_UI for this polygon dp_model_t *polygonbegin_model; + // indicates if polygonbegin should be interpreted as 2d + // (clearscene sets this to false, renderscene sets this to true, drawpic + // also sets this to true) + // note that in FTEQW polygonbegin with 2 args is handled very differently, + // where the behavior is always 3D unless DRAWFLAG_2D is passed, but + // DRAWFLAG_2D conflicts with our DRAWFLAG_SCREEN. + qboolean polygonbegin_guess2d; // copies of some vars that were former read from sv int num_edicts; diff --git a/prvm_cmds.c b/prvm_cmds.c index af6d27b9..7c7fa0ef 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -3350,6 +3350,9 @@ void VM_drawcharacter(prvm_prog_t *prog) float sx, sy; VM_SAFEPARMCOUNT(6,VM_drawcharacter); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + character = (char) PRVM_G_FLOAT(OFS_PARM1); if(character == 0) { @@ -3400,6 +3403,9 @@ void VM_drawstring(prvm_prog_t *prog) float sx, sy; VM_SAFEPARMCOUNTRANGE(5,6,VM_drawstring); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + string = PRVM_G_STRING(OFS_PARM1); pos = PRVM_G_VECTOR(OFS_PARM0); scale = PRVM_G_VECTOR(OFS_PARM2); @@ -3449,6 +3455,9 @@ void VM_drawcolorcodedstring(prvm_prog_t *prog) VM_SAFEPARMCOUNTRANGE(5,6,VM_drawcolorcodedstring); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + if (prog->argc == 6) // full 6 parms, like normal drawstring { pos = PRVM_G_VECTOR(OFS_PARM0); @@ -3734,6 +3743,9 @@ void VM_drawpic(prvm_prog_t *prog) VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM1); VM_CheckEmptyString(prog, picname); @@ -3779,6 +3791,9 @@ void VM_drawrotpic(prvm_prog_t *prog) VM_SAFEPARMCOUNT(8,VM_drawrotpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM1); VM_CheckEmptyString(prog, picname); @@ -3825,6 +3840,9 @@ void VM_drawsubpic(prvm_prog_t *prog) VM_SAFEPARMCOUNT(8,VM_drawsubpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM2); VM_CheckEmptyString(prog, picname); @@ -3878,6 +3896,8 @@ void VM_drawfill(prvm_prog_t *prog) VM_SAFEPARMCOUNT(5,VM_drawfill); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; pos = PRVM_G_VECTOR(OFS_PARM0); size = PRVM_G_VECTOR(OFS_PARM1); @@ -3910,6 +3930,9 @@ void VM_drawsetcliparea(prvm_prog_t *prog) float x,y,w,h; VM_SAFEPARMCOUNT(4,VM_drawsetcliparea); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid_conwidth.integer); y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid_conheight.integer); w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid_conwidth.integer - x)); @@ -3929,6 +3952,9 @@ void VM_drawresetcliparea(prvm_prog_t *prog) { VM_SAFEPARMCOUNT(0,VM_drawresetcliparea); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + DrawQ_ResetClipArea(); } @@ -4358,6 +4384,10 @@ void VM_drawline (prvm_prog_t *prog) unsigned char flags; VM_SAFEPARMCOUNT(6, VM_drawline); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + width = PRVM_G_FLOAT(OFS_PARM0); c1 = PRVM_G_VECTOR(OFS_PARM1); c2 = PRVM_G_VECTOR(OFS_PARM2); diff --git a/r_sprites.c b/r_sprites.c index d72bee10..5c621da4 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -416,6 +416,10 @@ static void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, R_CalcSprite_Vertex3f(vertex3f, org, left, up, frame->left, frame->right, frame->down, frame->up); + if (r_showspriteedges.integer) + for (i = 0; i < 4; i++) + R_DebugLine(vertex3f + i * 3, vertex3f + ((i + 1) % 4) * 3); + R_DrawCustomSurface_Texture(texture, &identitymatrix, texture->currentmaterialflags, 0, 4, 0, 2, false, false); } } diff --git a/render.h b/render.h index df88749a..39753cb0 100644 --- a/render.h +++ b/render.h @@ -600,7 +600,10 @@ void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rt void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); void R_SetupView(qboolean allowwaterclippingplane, int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); +void R_DebugLine(vec3_t start, vec3_t end); extern const float r_screenvertex3f[12]; +extern cvar_t r_showspriteedges; +extern cvar_t r_showparticleedges; extern cvar_t r_shadows; extern cvar_t r_shadows_darken; extern cvar_t r_shadows_drawafterrtlighting; -- 2.39.2