model: abstract renderer specific parts of sprite model loading

The differences between the software and GL renderers for sprite models boils
down to a) how much memory is allocated on the end of the mspriteframe_t struct
and b) how it processes the raw pixel data. Abstract these parts away so the
common parts can be shared.

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2012-11-14 09:15:49 +10:30
parent 357e7a35ed
commit fcb46ae327
7 changed files with 87 additions and 37 deletions

View File

@ -415,7 +415,7 @@ D_DrawSprite(void)
cachewidth = r_spritedesc.pspriteframe->width;
sprite_height = r_spritedesc.pspriteframe->height;
cacheblock = (byte *)&r_spritedesc.pspriteframe->pixels[0];
cacheblock = (byte *)&r_spritedesc.pspriteframe->rdata[0];
// copy the first vertex to the last vertex, so we don't have to deal with
// wrapping

View File

@ -1725,19 +1725,17 @@ Mod_LoadSpriteFrame(void *pin, mspriteframe_t **ppframe, const char *loadname,
{
dspriteframe_t *pinframe;
mspriteframe_t *pspriteframe;
int width, height, size, origin[2];
char name[MAX_QPATH];
int width, height, numpixels, size, origin[2];
pinframe = (dspriteframe_t *)pin;
width = LittleLong(pinframe->width);
height = LittleLong(pinframe->height);
size = width * height;
pspriteframe = Hunk_AllocName(sizeof(mspriteframe_t), loadname);
memset(pspriteframe, 0, sizeof(mspriteframe_t));
numpixels = width * height;
size = sizeof(mspriteframe_t) + R_SpriteDataSize(numpixels);
pspriteframe = Hunk_AllocName(size, loadname);
memset(pspriteframe, 0, size);
*ppframe = pspriteframe;
pspriteframe->width = width;
@ -1750,12 +1748,10 @@ Mod_LoadSpriteFrame(void *pin, mspriteframe_t **ppframe, const char *loadname,
pspriteframe->left = origin[0];
pspriteframe->right = width + origin[0];
snprintf(name, sizeof(name), "%s_%i", loadname, framenum);
pspriteframe->gl_texturenum =
GL_LoadTexture(name, width, height, (byte *)(pinframe + 1), true,
true);
/* Let the renderer process the pixel data as needed */
R_SpriteDataStore(pspriteframe, loadname, framenum, (byte *)(pinframe + 1));
return (void *)((byte *)pinframe + sizeof(dspriteframe_t) + size);
return (byte *)pinframe + sizeof(dspriteframe_t) + numpixels;
}

View File

@ -165,6 +165,22 @@ R_RotateForEntity(entity_t *e)
=============================================================
*/
int R_SpriteDataSize(int numpixels)
{
return sizeof(GLuint);
}
void R_SpriteDataStore(mspriteframe_t *frame, const char *modelname,
int framenum, byte *pixels)
{
char name[MAX_QPATH];
GLuint *gl_texturenum = (GLuint *)&frame->rdata[0];
snprintf(name, sizeof(name), "%s_%i", modelname, framenum);
*gl_texturenum = GL_LoadTexture(name, frame->width, frame->height, pixels,
true, true);
}
/*
================
R_GetSpriteFrame
@ -244,7 +260,7 @@ R_DrawSpriteModel(entity_t *e)
glColor3f(1, 1, 1);
GL_DisableMultitexture();
GL_Bind(frame->gl_texturenum);
GL_Bind(*(GLuint *)&frame->rdata[0]);
glEnable(GL_ALPHA_TEST);
glBegin(GL_QUADS);

View File

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// r_sprite.c
#include "console.h"
#include "model.h"
#include "quakedef.h"
#include "r_local.h"
#include "sys.h"
@ -30,6 +31,30 @@ static int sprite_width, sprite_height;
spritedesc_t r_spritedesc;
int
R_SpriteDataSize(int pixels)
{
return pixels * r_pixbytes;
}
void
R_SpriteDataStore(mspriteframe_t *frame, const char *modelname,
int framenum, byte *pixels)
{
int i, size;
size = frame->width * frame->height;
if (r_pixbytes == 1) {
memcpy(&frame->rdata[0], pixels, size);
} else if (r_pixbytes == 2) {
unsigned short *pixout = (unsigned short *)&frame->rdata[0];
for (i = 0; i < size; i++)
pixout[i] = d_8to16table[pixels[i]];
} else {
Sys_Error("%s: driver set invalid r_pixbytes: %d", __func__,
r_pixbytes);
}
}
/*
================

View File

@ -37,20 +37,17 @@ Mod_LoadSpriteFrame(void *pin, mspriteframe_t **ppframe, const char *loadname,
{
dspriteframe_t *pinframe;
mspriteframe_t *pspriteframe;
int i, width, height, size, origin[2];
unsigned short *ppixout;
byte *ppixin;
int width, height, numpixels, size, origin[2];
pinframe = (dspriteframe_t *)pin;
width = LittleLong(pinframe->width);
height = LittleLong(pinframe->height);
size = width * height;
numpixels = width * height;
size = sizeof(mspriteframe_t) + R_SpriteDataSize(numpixels);
pspriteframe =
Hunk_AllocName(sizeof(mspriteframe_t) + size * r_pixbytes, loadname);
memset(pspriteframe, 0, sizeof(mspriteframe_t) + size);
pspriteframe = Hunk_AllocName(size, loadname);
memset(pspriteframe, 0, size);
*ppframe = pspriteframe;
pspriteframe->width = width;
@ -63,20 +60,10 @@ Mod_LoadSpriteFrame(void *pin, mspriteframe_t **ppframe, const char *loadname,
pspriteframe->left = origin[0];
pspriteframe->right = width + origin[0];
if (r_pixbytes == 1) {
memcpy(&pspriteframe->pixels[0], (byte *)(pinframe + 1), size);
} else if (r_pixbytes == 2) {
ppixin = (byte *)(pinframe + 1);
ppixout = (unsigned short *)&pspriteframe->pixels[0];
/* Let the renderer process the pixel data as needed */
R_SpriteDataStore(pspriteframe, loadname, framenum, (byte *)(pinframe + 1));
for (i = 0; i < size; i++)
ppixout[i] = d_8to16table[ppixin[i]];
} else {
Sys_Error("%s: driver set invalid r_pixbytes: %d", __func__,
r_pixbytes);
}
return (void *)((byte *)pinframe + sizeof(dspriteframe_t) + size);
return (byte *)pinframe + sizeof(dspriteframe_t) + numpixels;
}

View File

@ -221,9 +221,22 @@ typedef struct mspriteframe_s {
int width;
int height;
float up, down, left, right;
int gl_texturenum;
byte rdata[0]; /* Renderer data, variable sized */
} mspriteframe_t;
/*
* Renderer provides this function to specify the amount of space it needs for
* a sprite frame with given pixel count
*/
int R_SpriteDataSize(int numpixels);
/*
* Renderer provides this function to translate and store the raw sprite data
* from the model file as needed.
*/
void R_SpriteDataStore(mspriteframe_t *frame, const char *modelname,
int framenum, byte *pixels);
typedef struct {
int numframes;
float *intervals;

View File

@ -201,9 +201,22 @@ typedef struct mspriteframe_s {
int width;
int height;
float up, down, left, right;
byte pixels[4];
byte rdata[0]; /* Renderer data, variable sized */
} mspriteframe_t;
/*
* Renderer provides this function to specify the amount of space it needs for
* a sprite frame with given pixel count
*/
int R_SpriteDataSize(int numpixels);
/*
* Renderer provides this function to translate and store the raw sprite data
* from the model file as needed.
*/
void R_SpriteDataStore(mspriteframe_t *frame, const char *modelname,
int framenum, byte *pixels);
typedef struct {
int numframes;
float *intervals;