From 6f18035c124d51a498650b2e2ec543318a023ed3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 5 Jan 2012 12:48:15 +0900 Subject: [PATCH] Fix up alias-16 support. After getting in contact with serplord, I now know that the sw alias loading was correct. Turns out the gl loaders was mostly correct, just a mistaken subtract rather than add. And with that, I can implement alias-16 support in glsl. better yet, since all the work is done in the loader, the renderer doesn't know anything about it :) However, I need to create some 16-bit models for testing. --- include/QF/GLSL/qf_alias.h | 8 +++++--- libs/models/alias/gl_mesh.c | 8 +++++++- libs/models/alias/glsl_model_alias.c | 9 ++++++++- libs/models/alias/sw_model_alias.c | 11 ++++------- libs/video/renderer/gl/gl_mod_alias.c | 2 ++ libs/video/renderer/glsl/glsl_alias.c | 2 +- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/include/QF/GLSL/qf_alias.h b/include/QF/GLSL/qf_alias.h index a9fe82786..dc852e52c 100644 --- a/include/QF/GLSL/qf_alias.h +++ b/include/QF/GLSL/qf_alias.h @@ -31,10 +31,12 @@ #ifndef __QF_GLSL_qf_alias_h #define __QF_GLSL_qf_alias_h +#include "QF/GLSL/types.h" + typedef struct aliasvrt_s { - short st[2]; - short normal[3]; - byte vertex[3]; + GLshort st[2]; + GLshort normal[3]; + GLushort vertex[3]; } aliasvrt_t; void R_InitAlias (void); diff --git a/libs/models/alias/gl_mesh.c b/libs/models/alias/gl_mesh.c index ada16b9f1..831084bf1 100644 --- a/libs/models/alias/gl_mesh.c +++ b/libs/models/alias/gl_mesh.c @@ -518,7 +518,13 @@ Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, i trivertx_t *pv = poseverts[i]; for (j = 0; j < numorder; j++) { trivertx16_t v; - VectorMultSub (pv[vertexorder[j] + hdr->mdl.numverts].v, + // convert MD16's split coordinates into something a little + // saner. The first chunk of vertices is fully compatible with + // IDPO alias models (even the scale). The second chunk is the + // fractional bits of the vertex, giving 8.8. However, it's + // easier for us to multiply everything by 256 and adjust the + // model scale appropriately + VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v, 256, pv[vertexorder[j]].v, v.v); v.lightnormalindex = poseverts[i][vertexorder[j]].lightnormalindex; diff --git a/libs/models/alias/glsl_model_alias.c b/libs/models/alias/glsl_model_alias.c index d050a110a..17f9f7b63 100644 --- a/libs/models/alias/glsl_model_alias.c +++ b/libs/models/alias/glsl_model_alias.c @@ -81,6 +81,8 @@ Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group, void Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr) { + if (hdr->mdl.ident == HEADER_MDL16) + VectorScale (hdr->mdl.scale, 1/256.0, hdr->mdl.scale); } void @@ -146,7 +148,12 @@ Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, for (i = 0, pose = 0; i < hdr->numposes; i++, pose += numverts) { for (j = 0; j < hdr->mdl.numverts; j++) { pv = &poseverts[i][j]; - VectorCopy (pv->v, verts[pose + j].vertex); + if (extra) { + VectorMultAdd (pv[hdr->numposes].v, 256, pv->v, + verts[pose + j].vertex); + } else { + VectorCopy (pv->v, verts[pose + j].vertex); + } verts[pose + j].st[0] = st[j].s; verts[pose + j].st[1] = st[j].t; VectorScale (vertex_normals[pv->lightnormalindex], 32767, diff --git a/libs/models/alias/sw_model_alias.c b/libs/models/alias/sw_model_alias.c index 7de992167..b444db04c 100644 --- a/libs/models/alias/sw_model_alias.c +++ b/libs/models/alias/sw_model_alias.c @@ -78,13 +78,10 @@ process_frame (maliasframedesc_t *frame, int posenum, int extra) frame_verts = Hunk_AllocName (size, loadname); frame->frame = (byte *) frame_verts - (byte *) pheader; - // I'm really not sure what the format of md16 is, but for now, I'll - // assume the sw renderer is correct (I believe that's what serplord - // was using when he developed it), which means the low-order 8 bits - // (actually, fractional) are completely separate from the high-order - // bits (see R_AliasTransformFinalVert16 in sw_ralias.c), but in - // adjacant arrays. This means we can get away with just one memcpy - // as there are non endian issues. + // The low-order 8 bits (actually, fractional) are completely separate + // from the high-order bits (see R_AliasTransformFinalVert16 in + // sw_ralias.c), but in adjacant arrays. This means we can get away with + // just one memcpy as there are non endian issues. memcpy (frame_verts, poseverts[posenum], size); } diff --git a/libs/video/renderer/gl/gl_mod_alias.c b/libs/video/renderer/gl/gl_mod_alias.c index a8b83a2e8..d58609275 100644 --- a/libs/video/renderer/gl/gl_mod_alias.c +++ b/libs/video/renderer/gl/gl_mod_alias.c @@ -538,6 +538,8 @@ R_DrawAliasModel (entity_t *e) } if (paliashdr->mdl.ident == HEADER_MDL16) { + // because we multipled by 256 when we loaded the verts, we have to + // scale by 1/256 when drawing. VectorScale (paliashdr->mdl.scale, e->scale / 256.0, scale); vo = GL_GetAliasFrameVerts16 (paliashdr, e); } else { diff --git a/libs/video/renderer/glsl/glsl_alias.c b/libs/video/renderer/glsl/glsl_alias.c index 49c1e3779..846a75455 100644 --- a/libs/video/renderer/glsl/glsl_alias.c +++ b/libs/video/renderer/glsl/glsl_alias.c @@ -165,7 +165,7 @@ set_arrays (const shaderparam_t *vert, const shaderparam_t *norm, const shaderparam_t *st, aliasvrt_t *pose) { byte *pose_offs = (byte *) pose; - qfglVertexAttribPointer (vert->location, 3, GL_UNSIGNED_BYTE, + qfglVertexAttribPointer (vert->location, 3, GL_UNSIGNED_SHORT, 0, sizeof (aliasvrt_t), pose_offs + field_offset (aliasvrt_t, vertex)); qfglVertexAttribPointer (norm->location, 3, GL_SHORT,