From dedaa3df678d0cc959a2884d8e2c4159a9b1fb30 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Aug 2007 12:23:25 +0000 Subject: [PATCH] new sprite types SPR_LABEL and SPR_LABEL_SCALE git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7536 d7cf8633-e32d-0410-b094-e92efae38249 --- model_sprite.c | 4 +++ r_sprites.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-- spritegn.h | 2 ++ 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/model_sprite.c b/model_sprite.c index d22f105f..94b5b372 100644 --- a/model_sprite.c +++ b/model_sprite.c @@ -27,6 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t r_mipsprites = {CVAR_SAVE, "r_mipsprites", "1", "mipmaps sprites so they render faster in the distance and do not display noise artifacts"}; cvar_t r_picmipsprites = {CVAR_SAVE, "r_picmipsprites", "1", "make gl_picmip affect sprites too (saves some graphics memory in sprite heavy games)"}; +cvar_t r_labelsprites_scale = {CVAR_SAVE, "r_labelsprites_scale", "1", "global scale to apply to label sprites before conversion to HUD coordinates"}; +cvar_t r_labelsprites_roundtopixels = {CVAR_SAVE, "r_labelsprites_roundtopixels", "1", "try to make label sprites sharper by rounding their size to 0.5x or 1x and by rounding their position to whole pixels if possible"}; /* =============== @@ -37,6 +39,8 @@ void Mod_SpriteInit (void) { Cvar_RegisterVariable(&r_mipsprites); Cvar_RegisterVariable(&r_picmipsprites); + Cvar_RegisterVariable(&r_labelsprites_scale); + Cvar_RegisterVariable(&r_labelsprites_roundtopixels); } static void Mod_SpriteSetupTexture(texture_t *texture, skinframe_t *skinframe, qboolean fullbright, qboolean additive) diff --git a/r_sprites.c b/r_sprites.c index 6c8126b7..c514b812 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -2,12 +2,15 @@ #include "quakedef.h" #include "r_shadow.h" +extern cvar_t r_labelsprites_scale; +extern cvar_t r_labelsprites_roundtopixels; + void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { int i; model_t *model = ent->model; - vec3_t left, up, org, mforward, mleft, mup; - float scale; + vec3_t left, up, org, mforward, mleft, mup, middle; + float scale, dx, dy, hud_vs_screen; // nudge it toward the view to make sure it isn't in a wall Matrix4x4_ToVectors(&ent->matrix, mforward, mleft, mup, org); @@ -45,6 +48,75 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r VectorScale(r_view.left, ent->scale, left); VectorScale(r_view.up, ent->scale, up); break; + case SPR_LABEL_SCALE: + // normal sprite + // faces view plane + // fixed HUD pixel size specified in sprite + // honors scale + // honors a global label scaling cvar + + scale = 2 * ent->scale * (DotProduct(r_view.forward, org) - DotProduct(r_view.forward, r_view.origin)) * r_labelsprites_scale.value; + VectorScale(r_view.left, scale * r_view.frustum_x / vid_conwidth.integer, left); // 1px + VectorScale(r_view.up, scale * r_view.frustum_y / vid_conheight.integer, up); // 1px + break; + case SPR_LABEL: + // normal sprite + // faces view plane + // fixed pixel size specified in sprite + // tries to get the right size in HUD units, if possible + // ignores scale + // honors a global label scaling cvar before the rounding + // FIXME assumes that 1qu is 1 pixel in the sprite like in SPR32 format. Should not do that, but instead query the source image! This bug only applies to the roundtopixels case, though. + + scale = 2 * (DotProduct(r_view.forward, org) - DotProduct(r_view.forward, r_view.origin)); + + if(r_labelsprites_roundtopixels.integer) + { + hud_vs_screen = max( + vid_conwidth.integer / (float) r_view.width, + vid_conheight.integer / (float) r_view.height + ) / max(0.125, r_labelsprites_scale.value); + + // snap to "good sizes" + // 1 for (0.6, 1.41] + // 2 for (1.8, 3.33] + if(hud_vs_screen <= 0.6) + hud_vs_screen = 0; // don't, use real HUD pixels + else if(hud_vs_screen <= 1.41) + hud_vs_screen = 1; + else if(hud_vs_screen <= 3.33) + hud_vs_screen = 2; + else + hud_vs_screen = 0; // don't, use real HUD pixels + + if(hud_vs_screen) + { + // use screen pixels + VectorScale(r_view.left, scale * r_view.frustum_x / (r_view.width * hud_vs_screen), left); // 1px + VectorScale(r_view.up, scale * r_view.frustum_y / (r_view.height * hud_vs_screen), up); // 1px + } + else + { + // use HUD pixels + VectorScale(r_view.left, scale * r_view.frustum_x / vid_conwidth.integer * r_labelsprites_scale.value, left); // 1px + VectorScale(r_view.up, scale * r_view.frustum_y / vid_conheight.integer * r_labelsprites_scale.value, up); // 1px + } + + if(hud_vs_screen == 1) + { + VectorMA(r_view.origin, scale, r_view.forward, middle); // center of screen in distance scale + dx = 0.5 - fmod(r_view.width * 0.5 + (DotProduct(org, left) - DotProduct(middle, left)) / DotProduct(left, left) + 0.5, 1.0); + dy = 0.5 - fmod(r_view.height * 0.5 + (DotProduct(org, up) - DotProduct(middle, up)) / DotProduct(up, up) + 0.5, 1.0); + VectorMAMAM(1, org, dx, left, dy, up, org); + } + } + else + { + // use HUD pixels + VectorScale(r_view.left, scale * r_view.frustum_x / vid_conwidth.integer * r_labelsprites_scale.value, left); // 1px + VectorScale(r_view.up, scale * r_view.frustum_y / vid_conheight.integer * r_labelsprites_scale.value, up); // 1px + } + break; case SPR_ORIENTED: // bullet marks on walls // ignores viewer entirely diff --git a/spritegn.h b/spritegn.h index 1f43025b..26edb1a4 100644 --- a/spritegn.h +++ b/spritegn.h @@ -98,6 +98,8 @@ typedef struct dsprite2_s #define SPR_VP_PARALLEL 2 #define SPR_ORIENTED 3 #define SPR_VP_PARALLEL_ORIENTED 4 +#define SPR_LABEL 5 +#define SPR_LABEL_SCALE 6 #define SPRHL_OPAQUE 0 #define SPRHL_ADDITIVE 1 -- 2.39.2