[renderer] Start merging sprite frame calculation

This covers gl and sw. sw32 should be trivial (just haven't done it),
but glsl will take a little. Vulkan will use it.
This commit is contained in:
Bill Currie 2021-12-15 01:18:02 +09:00
parent 743a732bd7
commit dafe591446
5 changed files with 81 additions and 91 deletions

View File

@ -95,5 +95,7 @@ void GLSL_SetPalette (void *data, const byte *palette);
int R_BillboardFrame (entity_t *ent, int orientation, const vec3_t cameravec,
vec3_t bbup, vec3_t bbright, vec3_t bbpn);
mspriteframe_t *R_GetSpriteFrame (const msprite_t *sprite,
const animation_t *animation);
#endif//__r_internal_h

View File

@ -39,6 +39,7 @@ video_renderer_common_sources = \
libs/video/renderer/r_light.c \
libs/video/renderer/r_main.c \
libs/video/renderer/r_part.c \
libs/video/renderer/r_sprite.c \
libs/video/renderer/vid_common.c
renderer_libs= \

View File

@ -57,50 +57,6 @@ varray_t2f_c4ub_v3f_t *gl_spriteVertexArray;
void (*gl_R_DrawSpriteModel) (struct entity_s *ent);
static mspriteframe_t *
R_GetSpriteFrame (entity_t *ent)
{
float fullinterval, targettime, time;
float *pintervals;
int frame, numframes, i;
msprite_t *psprite;
mspriteframe_t *pspriteframe;
mspritegroup_t *pspritegroup;
psprite = ent->renderer.model->cache.data;
frame = ent->animation.frame;
if ((frame >= psprite->numframes) || (frame < 0)) {
Sys_MaskPrintf (SYS_dev, "R_DrawSprite: no such frame %d\n", frame);
frame = 0;
}
if (psprite->frames[frame].type == SPR_SINGLE) {
pspriteframe = psprite->frames[frame].frame;
} else {
pspritegroup = psprite->frames[frame].group;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
time = vr_data.realtime + ent->animation.syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
targettime = time - ((int) (time / fullinterval)) * fullinterval;
for (i = 0; i < (numframes - 1); i++) {
if (pintervals[i] > targettime)
break;
}
pspriteframe = pspritegroup->frames[i];
}
return pspriteframe;
}
static void
R_DrawSpriteModel_f (entity_t *e)
{
@ -116,7 +72,7 @@ R_DrawSpriteModel_f (entity_t *e)
cameravec -= origin;
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
frame = R_GetSpriteFrame (sprite, &e->animation);
if (!R_BillboardFrame (e, sprite->type, &cameravec[0],
&up[0], &right[0], &pn[0])) {
@ -167,15 +123,14 @@ R_DrawSpriteModel_VA_f (entity_t *e)
vec4f_t origin, point;
int i;
// unsigned int vacount;
msprite_t *psprite;
msprite_t *psprite = e->renderer.model->cache.data;
mspriteframe_t *frame;
varray_t2f_c4ub_v3f_t *VA;
VA = gl_spriteVertexArray; // FIXME: Despair
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->renderer.model->cache.data;
frame = R_GetSpriteFrame (psprite, &e->animation);
qfglBindTexture (GL_TEXTURE_2D, frame->gl_texturenum); // FIXME: DESPAIR

View File

@ -0,0 +1,73 @@
/*
r_sprite.c
Draw Sprite Model
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/sys.h"
#include "r_internal.h"
mspriteframe_t *
R_GetSpriteFrame (const msprite_t *sprite, const animation_t *animation)
{
mspritegroup_t *group;
mspriteframe_t *frame;
int i, numframes, frame_num;
float *intervals, fullinterval, targettime, time;
frame_num = animation->frame;
if ((frame_num >= sprite->numframes) || (frame_num < 0)) {
Sys_Printf ("R_DrawSprite: no such frame %d\n", frame_num);
frame_num = 0;
}
if (sprite->frames[frame_num].type == SPR_SINGLE) {
frame = sprite->frames[frame_num].frame;
} else {
group = sprite->frames[frame_num].group;
intervals = group->intervals;
numframes = group->numframes;
fullinterval = intervals[numframes - 1];
time = vr_data.realtime + animation->syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
targettime = time - ((int) (time / fullinterval)) * fullinterval;
for (i = 0; i < (numframes - 1); i++) {
if (intervals[i] > targettime)
break;
}
frame = group->frames[i];
}
return frame;
}

View File

@ -239,54 +239,13 @@ R_SetupAndDrawSprite (void)
D_DrawSprite ();
}
static mspriteframe_t *
R_GetSpriteframe (msprite_t *psprite)
{
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
frame = currententity->animation.frame;
if ((frame >= psprite->numframes) || (frame < 0)) {
Sys_Printf ("R_DrawSprite: no such frame %d\n", frame);
frame = 0;
}
if (psprite->frames[frame].type == SPR_SINGLE) {
pspriteframe = psprite->frames[frame].frame;
} else {
pspritegroup = psprite->frames[frame].group;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
time = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
targettime = time - ((int) (time / fullinterval)) * fullinterval;
for (i = 0; i < (numframes - 1); i++) {
if (pintervals[i] > targettime)
break;
}
pspriteframe = pspritegroup->frames[i];
}
return pspriteframe;
}
void
R_DrawSprite (void)
{
msprite_t *sprite = currententity->renderer.model->cache.data;
r_spritedesc.pspriteframe = R_GetSpriteframe (sprite);
r_spritedesc.pspriteframe = R_GetSpriteFrame (sprite,
&currententity->animation);
sprite_width = r_spritedesc.pspriteframe->width;
sprite_height = r_spritedesc.pspriteframe->height;