attempt to support quakeforge 16bit mdl variant. untested.

This commit is contained in:
Shpoike 2019-01-30 01:54:49 +00:00
parent 3a7caf60c3
commit daac6039a5
4 changed files with 273 additions and 160 deletions

View File

@ -107,11 +107,28 @@ void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *paliashdr)
}
}
verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->numverts_vbo * sizeof(*verts));
paliashdr->vertexes = (byte *)verts - (byte *)paliashdr;
for (i=0 ; i<paliashdr->numposes ; i++)
for (j=0 ; j<paliashdr->numverts_vbo ; j++)
verts[i*paliashdr->numverts_vbo + j] = poseverts_mdl[i][desc[j].vertindex];
switch(paliashdr->poseverttype)
{
case PV_QUAKEFORGE:
verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->numverts_vbo*2 * sizeof(*verts));
paliashdr->vertexes = (byte *)verts - (byte *)paliashdr;
for (i=0 ; i<paliashdr->numposes ; i++)
for (j=0 ; j<paliashdr->numverts_vbo ; j++)
{
verts[i*paliashdr->numverts_vbo*2 + j] = poseverts_mdl[i][desc[j].vertindex];
verts[i*paliashdr->numverts_vbo*2 + j + paliashdr->numverts_vbo] = poseverts_mdl[i][desc[j].vertindex + paliashdr->numverts_vbo];
}
break;
case PV_QUAKE1:
verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->numverts_vbo * sizeof(*verts));
paliashdr->vertexes = (byte *)verts - (byte *)paliashdr;
for (i=0 ; i<paliashdr->numposes ; i++)
for (j=0 ; j<paliashdr->numverts_vbo ; j++)
verts[i*paliashdr->numverts_vbo + j] = poseverts_mdl[i][desc[j].vertindex];
break;
case PV_QUAKE3:
break; //invalid here.
}
}
#define NUMVERTEXNORMALS 162
@ -147,10 +164,18 @@ void GLMesh_LoadVertexBuffer (qmodel_t *m, aliashdr_t *mainhdr)
//count how much space we're going to need.
for(hdr = mainhdr, numverts = 0, numindexes = 0; ; )
{
if (hdr->posevertssize == 1)
switch(hdr->poseverttype)
{
case PV_QUAKE1:
totalvbosize += (hdr->numposes * hdr->numverts_vbo * sizeof (meshxyz_mdl_t)); // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm
else if (hdr->posevertssize == 2)
totalvbosize += (hdr->numposes * hdr->numverts_vbo * sizeof (meshxyz_md3_t)); // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm
break;
case PV_QUAKEFORGE:
totalvbosize += (hdr->numposes * hdr->numverts_vbo * sizeof (meshxyz_mdl16_t));
break;
case PV_QUAKE3:
totalvbosize += (hdr->numposes * hdr->numverts_vbo * sizeof (meshxyz_md3_t));
break;
}
numverts += hdr->numverts_vbo;
numindexes += hdr->numindexes;
@ -200,8 +225,9 @@ void GLMesh_LoadVertexBuffer (qmodel_t *m, aliashdr_t *mainhdr)
hdr->vbovertofs = vertofs;
// fill in the vertices at the start of the buffer
if (hdr->posevertssize == 1)
switch(hdr->poseverttype)
{
case PV_QUAKE1:
for (f = 0; f < hdr->numposes; f++) // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm
{
int v;
@ -225,9 +251,33 @@ void GLMesh_LoadVertexBuffer (qmodel_t *m, aliashdr_t *mainhdr)
xyz[v].normal[3] = 0; // unused; for 4-byte alignment
}
}
}
else if (hdr->posevertssize == 2)
{
break;
case PV_QUAKEFORGE:
for (f = 0; f < hdr->numposes; f++) // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm
{
int v;
meshxyz_mdl16_t *xyz = (meshxyz_mdl16_t *) (vbodata + vertofs);
const trivertx_t *tv = (trivertx_t*)trivertexes + (hdr->numverts_vbo*2 * f);
vertofs += hdr->numverts_vbo * sizeof (*xyz);
for (v = 0; v < hdr->numverts_vbo; v++, tv++)
{
xyz[v].xyz[0] = (tv->v[0]<<8) | tv[hdr->numverts_vbo].v[0];
xyz[v].xyz[1] = (tv->v[1]<<8) | tv[hdr->numverts_vbo].v[0];
xyz[v].xyz[2] = (tv->v[2]<<8) | tv[hdr->numverts_vbo].v[0];
xyz[v].xyz[3] = 1; // need w 1 for 4 byte vertex compression
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
xyz[v].normal[0] = 127 * r_avertexnormals[tv->lightnormalindex][0];
xyz[v].normal[1] = 127 * r_avertexnormals[tv->lightnormalindex][1];
xyz[v].normal[2] = 127 * r_avertexnormals[tv->lightnormalindex][2];
xyz[v].normal[3] = 0; // unused; for 4-byte alignment
}
}
break;
case PV_QUAKE3:
for (f = 0; f < hdr->numposes; f++) // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm
{
int v;
@ -254,6 +304,7 @@ void GLMesh_LoadVertexBuffer (qmodel_t *m, aliashdr_t *mainhdr)
xyz[v].normal[3] = 0; // unused; for 4-byte alignment
}
}
break;
}
// fill in the ST coords at the end of the buffer
@ -269,21 +320,23 @@ void GLMesh_LoadVertexBuffer (qmodel_t *m, aliashdr_t *mainhdr)
hdr->vbostofs = stofs;
st = (meshst_t *) (vbodata + stofs);
stofs += hdr->numverts_vbo*sizeof(*st);
if (hdr->posevertssize == 2)
switch(hdr->poseverttype)
{
case PV_QUAKE3:
for (f = 0; f < hdr->numverts_vbo; f++)
{ //md3 has floating-point skin coords. use the values directly.
st[f].st[0] = hscale * desc[f].st[0];
st[f].st[1] = vscale * desc[f].st[1];
}
}
else
{
break;
case PV_QUAKEFORGE:
case PV_QUAKE1:
for (f = 0; f < hdr->numverts_vbo; f++)
{
st[f].st[0] = hscale * ((float) desc[f].st[0] + 0.5f) / (float) hdr->skinwidth;
st[f].st[1] = vscale * ((float) desc[f].st[1] + 0.5f) / (float) hdr->skinheight;
}
break;
}
}
@ -528,7 +581,7 @@ void Mod_LoadMD3Model (qmodel_t *mod, void *buffer)
else
osurf->nextsurface = 0;
osurf->posevertssize = 2;
osurf->poseverttype = PV_QUAKE3;
osurf->numverts_vbo = osurf->numverts = LittleLong(pinsurface->numVerts);
pinvert = (md3XyzNormal_t*)((byte*)pinsurface + LittleLong(pinsurface->ofsXyzNormals));
poutvert = (md3XyzNormal_t *) Hunk_Alloc (numframes * osurf->numverts * sizeof(*poutvert));

View File

@ -31,7 +31,7 @@ char loadname[32]; // for hunk tags
void Mod_LoadSpriteModel (qmodel_t *mod, void *buffer);
void Mod_LoadBrushModel (qmodel_t *mod, void *buffer);
void Mod_LoadAliasModel (qmodel_t *mod, void *buffer);
void Mod_LoadAliasModel (qmodel_t *mod, void *buffer, int pvtype);
void Mod_LoadMD3Model (qmodel_t *mod, void *buffer);
qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash);
@ -373,7 +373,10 @@ qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash)
switch (mod_type)
{
case IDPOLYHEADER:
Mod_LoadAliasModel (mod, buf);
Mod_LoadAliasModel (mod, buf, PV_QUAKE1);
break;
case (('M'<<0)+('D'<<8)+('1'<<16)+('6'<<24)): //QF 16bit variation
Mod_LoadAliasModel (mod, buf, PV_QUAKEFORGE);
break;
case IDSPRITEHEADER:
@ -1446,8 +1449,8 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2)
if (Mod_ParseWorldspawnKey(loadmodel, "lightmap_scale", scalebuf, sizeof(scalebuf)))
{
i = atoi(scalebuf);
for (defaultshift = 0; (1<<defaultshift) < i && defaultshift < 254; defaultshift++)
break;
for(defaultshift = 0; i > 1; defaultshift++)
i >>= 1;
}
}
@ -2583,7 +2586,7 @@ byte *player_8bit_texels;
Mod_LoadAliasFrame
=================
*/
void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
static void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame, int pvtype)
{
trivertx_t *pinframe;
int i;
@ -2612,7 +2615,7 @@ void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
poseverts_mdl[posenum] = pinframe;
posenum++;
pinframe += pheader->numverts;
pinframe += pheader->numverts*(pvtype==PV_QUAKEFORGE?2:1);
return (void *)pinframe;
}
@ -2623,7 +2626,7 @@ void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame)
Mod_LoadAliasGroup
=================
*/
void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame)
static void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame, int pvtype)
{
daliasgroup_t *pingroup;
int i, numframes;
@ -2660,7 +2663,7 @@ void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame)
poseverts_mdl[posenum] = (trivertx_t *)((daliasframe_t *)ptemp + 1);
posenum++;
ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->numverts;
ptemp = (trivertx_t *)((daliasframe_t *)ptemp + 1) + pheader->numverts*(pvtype==PV_QUAKEFORGE?2:1);
}
return ptemp;
@ -2878,8 +2881,9 @@ void Mod_CalcAliasBounds (aliashdr_t *a)
{
if (a->numposes && a->numverts)
{
if (a->posevertssize == 1)
switch(a->poseverttype)
{
case PV_QUAKE1:
//process verts
for (i=0 ; i<a->numposes; i++)
for (j=0; j<a->numverts; j++)
@ -2899,9 +2903,29 @@ void Mod_CalcAliasBounds (aliashdr_t *a)
if (radius < dist)
radius = dist;
}
}
else if (a->posevertssize == 2)
{
break;
case PV_QUAKEFORGE:
//process verts
for (i=0 ; i<a->numposes; i++)
for (j=0; j<a->numverts; j++)
{
for (k=0; k<3;k++)
v[k] = (poseverts_mdl[i][j].v[k] * pheader->scale[k]) + (poseverts_mdl[i][j+a->numverts].v[k] * pheader->scale[k]/256.f) + (pheader->scale_origin[k]);
for (k=0; k<3;k++)
{
loadmodel->mins[k] = q_min(loadmodel->mins[k], v[k]);
loadmodel->maxs[k] = q_max(loadmodel->maxs[k], v[k]);
}
dist = v[0] * v[0] + v[1] * v[1];
if (yawradius < dist)
yawradius = dist;
dist += v[2] * v[2];
if (radius < dist)
radius = dist;
}
break;
case PV_QUAKE3:
//process verts
for (i=0 ; i<a->numposes; i++)
{
@ -2924,6 +2948,7 @@ void Mod_CalcAliasBounds (aliashdr_t *a)
radius = dist;
}
}
break;
}
}
@ -3028,7 +3053,7 @@ void Mod_SetExtraFlags (qmodel_t *mod)
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (qmodel_t *mod, void *buffer)
void Mod_LoadAliasModel (qmodel_t *mod, void *buffer, int pvtype)
{
int i, j;
mdl_t *pinmodel;
@ -3175,13 +3200,13 @@ void Mod_LoadAliasModel (qmodel_t *mod, void *buffer)
aliasframetype_t frametype;
frametype = (aliasframetype_t) LittleLong (pframetype->type);
if (frametype == ALIAS_SINGLE)
pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]);
pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i], pvtype);
else
pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]);
pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i], pvtype);
}
pheader->numposes = posenum;
pheader->posevertssize = 1;
pheader->poseverttype = pvtype; //it would be safe to always store PV_QUAKE1 here if you wanted to drop the low-order data.
mod->type = mod_alias;

View File

@ -293,6 +293,12 @@ typedef struct meshxyz_mdl_s
signed char normal[4];
} meshxyz_mdl_t;
typedef struct meshxyz_mdl16_s
{
unsigned short xyz[4];
signed char normal[4];
} meshxyz_mdl16_t;
typedef struct meshxyz_md3_s
{
signed short xyz[4];
@ -369,7 +375,12 @@ typedef struct {
intptr_t nextsurface; //spike
int numposes;
int posevertssize; //spike 1=mdl, 2=md3
enum
{
PV_QUAKE1 = 1, //trivertx_t
PV_QUAKE3 = 2, //md3XyzNormal_t
PV_QUAKEFORGE, //trivertx16_t
} poseverttype; //spike
struct gltexture_s *gltextures[MAX_SKINS][4]; //johnfitz
struct gltexture_s *fbtextures[MAX_SKINS][4]; //johnfitz
intptr_t texels[MAX_SKINS]; // only for player skins

View File

@ -99,6 +99,11 @@ static void *GLARB_GetXYZOffset_MDL (aliashdr_t *hdr, int pose)
const size_t xyzoffs = offsetof (meshxyz_mdl_t, xyz);
return currententity->model->meshvboptr+(hdr->vbovertofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_mdl_t)) + xyzoffs);
}
static void *GLARB_GetXYZOffset_MDLQF (aliashdr_t *hdr, int pose)
{
const size_t xyzoffs = offsetof (meshxyz_mdl16_t, xyz);
return currententity->model->meshvboptr+(hdr->vbovertofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_mdl16_t)) + xyzoffs);
}
static void *GLARB_GetXYZOffset_MD3 (aliashdr_t *hdr, int pose)
{
const size_t xyzoffs = offsetof (meshxyz_md3_t, xyz);
@ -118,6 +123,11 @@ static void *GLARB_GetNormalOffset_MDL (aliashdr_t *hdr, int pose)
const size_t normaloffs = offsetof (meshxyz_mdl_t, normal);
return currententity->model->meshvboptr+(hdr->vbovertofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_mdl_t)) + normaloffs);
}
static void *GLARB_GetNormalOffset_MDLQF (aliashdr_t *hdr, int pose)
{
const size_t normaloffs = offsetof (meshxyz_mdl16_t, normal);
return currententity->model->meshvboptr+(hdr->vbovertofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_mdl16_t)) + normaloffs);
}
static void *GLARB_GetNormalOffset_MD3 (aliashdr_t *hdr, int pose)
{
const size_t normaloffs = offsetof (meshxyz_md3_t, normal);
@ -260,21 +270,29 @@ void GL_DrawAliasFrame_GLSL (aliashdr_t *paliashdr, lerpdata_t lerpdata, gltextu
GL_EnableVertexAttribArrayFunc (pose2NormalAttrIndex);
GL_VertexAttribPointerFunc (texCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, 0, currententity->model->meshvboptr+paliashdr->vbostofs);
if (paliashdr->posevertssize == 1)
switch(paliashdr->poseverttype)
{
case PV_QUAKE1:
GL_VertexAttribPointerFunc (pose1VertexAttrIndex, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof (meshxyz_mdl_t), GLARB_GetXYZOffset_MDL (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2VertexAttrIndex, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof (meshxyz_mdl_t), GLARB_GetXYZOffset_MDL (paliashdr, lerpdata.pose2));
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc (pose1NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_mdl_t), GLARB_GetNormalOffset_MDL (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_mdl_t), GLARB_GetNormalOffset_MDL (paliashdr, lerpdata.pose2));
}
else if (paliashdr->posevertssize == 2)
{
break;
case PV_QUAKEFORGE:
GL_VertexAttribPointerFunc (pose1VertexAttrIndex, 4, GL_UNSIGNED_SHORT, GL_FALSE, sizeof (meshxyz_mdl16_t), GLARB_GetXYZOffset_MDLQF (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2VertexAttrIndex, 4, GL_UNSIGNED_SHORT, GL_FALSE, sizeof (meshxyz_mdl16_t), GLARB_GetXYZOffset_MDLQF (paliashdr, lerpdata.pose2));
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc (pose1NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_mdl16_t), GLARB_GetNormalOffset_MDLQF (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_mdl16_t), GLARB_GetNormalOffset_MDLQF (paliashdr, lerpdata.pose2));
break;
case PV_QUAKE3:
GL_VertexAttribPointerFunc (pose1VertexAttrIndex, 4, GL_SHORT, GL_FALSE, sizeof (meshxyz_md3_t), GLARB_GetXYZOffset_MD3 (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2VertexAttrIndex, 4, GL_SHORT, GL_FALSE, sizeof (meshxyz_md3_t), GLARB_GetXYZOffset_MD3 (paliashdr, lerpdata.pose2));
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc (pose1NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_md3_t), GLARB_GetNormalOffset_MD3 (paliashdr, lerpdata.pose1));
GL_VertexAttribPointerFunc (pose2NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_md3_t), GLARB_GetNormalOffset_MD3 (paliashdr, lerpdata.pose2));
break;
}
// set uniforms
@ -347,146 +365,152 @@ void GL_DrawAliasFrame (aliashdr_t *paliashdr, lerpdata_t lerpdata)
}
glEnableClientState(GL_VERTEX_ARRAY);
if (paliashdr->posevertssize == 1)
switch(paliashdr->poseverttype)
{
trivertx_t *verts1 = (trivertx_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose1 * paliashdr->numverts_vbo;
trivertx_t *verts2 = (trivertx_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose2 * paliashdr->numverts_vbo;
if (iblend)
case PV_QUAKE1:
case PV_QUAKEFORGE: //just going to ignore the extra data here.
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vpos[i][0] = verts1[i].v[0] * iblend + blend * verts2[i].v[0];
vpos[i][1] = verts1[i].v[1] * iblend + blend * verts2[i].v[1];
vpos[i][2] = verts1[i].v[2] * iblend + blend * verts2[i].v[2];
}
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
trivertx_t *verts1 = (trivertx_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose1 * paliashdr->numverts_vbo*(paliashdr->poseverttype==PV_QUAKEFORGE?2:1);
trivertx_t *verts2 = (trivertx_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose2 * paliashdr->numverts_vbo*(paliashdr->poseverttype==PV_QUAKEFORGE?2:1);
if (shading)
if (iblend)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vc[i][0] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[0];
vc[i][1] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[1];
vc[i][2] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[2];
vc[i][3] = entalpha;
vpos[i][0] = verts1[i].v[0] * iblend + blend * verts2[i].v[0];
vpos[i][1] = verts1[i].v[1] * iblend + blend * verts2[i].v[1];
vpos[i][2] = verts1[i].v[2] * iblend + blend * verts2[i].v[2];
}
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(*vc), vc);
}
}
else
{
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vc[i][0] = shadedots[verts2->lightnormalindex] * lightcolor[0];
vc[i][1] = shadedots[verts2->lightnormalindex] * lightcolor[1];
vc[i][2] = shadedots[verts2->lightnormalindex] * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glColorPointer(4, GL_FLOAT, 0, vc);
}
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
//glVertexPointer may not take GL_UNSIGNED_BYTE, which means we can't use our vbos. attribute 0 MAY be vertex coords, but I don't want to depend on that.
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vpos[i][0] = verts2[i].v[0];
vpos[i][1] = verts2[i].v[1];
vpos[i][2] = verts2[i].v[2];
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vc[i][0] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[0];
vc[i][1] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[1];
vc[i][2] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(*vc), vc);
}
}
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
}
}
else if (paliashdr->posevertssize == 2)
{
md3XyzNormal_t *verts1 = (md3XyzNormal_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose1 * paliashdr->numverts_vbo;
md3XyzNormal_t *verts2 = (md3XyzNormal_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose2 * paliashdr->numverts_vbo;
if (iblend)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
else
{
vpos[i][0] = verts1[i].xyz[0] * iblend + blend * verts2[i].xyz[0];
vpos[i][1] = verts1[i].xyz[1] * iblend + blend * verts2[i].xyz[1];
vpos[i][2] = verts1[i].xyz[2] * iblend + blend * verts2[i].xyz[2];
}
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vc[i][0] = shadedots[verts2->lightnormalindex] * lightcolor[0];
vc[i][1] = shadedots[verts2->lightnormalindex] * lightcolor[1];
vc[i][2] = shadedots[verts2->lightnormalindex] * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glColorPointer(4, GL_FLOAT, 0, vc);
}
if (shading)
{
//glVertexPointer may not take GL_UNSIGNED_BYTE, which means we can't use our vbos. attribute 0 MAY be vertex coords, but I don't want to depend on that.
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vec3_t n;
float dot;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = (float)verts2[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)verts2[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] = blend * cos ( lng ) * sin ( lat );
n[1] = blend * sin ( lng ) * sin ( lat );
n[2] = blend * cos ( lat );
lat = (float)verts1[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
lng = (float)verts1[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] += iblend * cos ( lng ) * sin ( lat );
n[1] += iblend * sin ( lng ) * sin ( lat );
n[2] += iblend * cos ( lat );
dot = DotProduct(n, shadevector);
if (dot < 0.0) //bizzare maths guessed by mh
dot = 1.0 + dot * (13.0 / 44.0);
else
dot = 1.0 + dot;
vc[i][0] = dot * lightcolor[0];
vc[i][1] = dot * lightcolor[1];
vc[i][2] = dot * lightcolor[2];
vc[i][3] = entalpha;
vpos[i][0] = verts2[i].v[0];
vpos[i][1] = verts2[i].v[1];
vpos[i][2] = verts2[i].v[2];
}
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, vc);
}
}
else
{
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vec3_t n;
float dot;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = (float)verts2[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)verts2[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] = cos ( lng ) * sin ( lat );
n[1] = sin ( lng ) * sin ( lat );
n[2] = cos ( lat );
dot = DotProduct(n, shadevector);
if (dot < 0.0) //bizzare maths guessed by mh
dot = 1.0 + dot * (13.0 / 44.0);
else
dot = 1.0 + dot;
vc[i][0] = dot * lightcolor[0];
vc[i][1] = dot * lightcolor[1];
vc[i][2] = dot * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glColorPointer(4, GL_FLOAT, 0, vc);
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
}
GL_BindBuffer (GL_ARRAY_BUFFER, currententity->model->meshvbo);
glVertexPointer(3, GL_SHORT, sizeof (meshxyz_md3_t), GLARB_GetXYZOffset_MD3 (paliashdr, lerpdata.pose2));
}
break;
case PV_QUAKE3:
{
md3XyzNormal_t *verts1 = (md3XyzNormal_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose1 * paliashdr->numverts_vbo;
md3XyzNormal_t *verts2 = (md3XyzNormal_t*)((byte *)paliashdr + paliashdr->vertexes) + lerpdata.pose2 * paliashdr->numverts_vbo;
if (iblend)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vpos[i][0] = verts1[i].xyz[0] * iblend + blend * verts2[i].xyz[0];
vpos[i][1] = verts1[i].xyz[1] * iblend + blend * verts2[i].xyz[1];
vpos[i][2] = verts1[i].xyz[2] * iblend + blend * verts2[i].xyz[2];
}
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, sizeof (vpos[0]), vpos);
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vec3_t n;
float dot;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = (float)verts2[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)verts2[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] = blend * cos ( lng ) * sin ( lat );
n[1] = blend * sin ( lng ) * sin ( lat );
n[2] = blend * cos ( lat );
lat = (float)verts1[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
lng = (float)verts1[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] += iblend * cos ( lng ) * sin ( lat );
n[1] += iblend * sin ( lng ) * sin ( lat );
n[2] += iblend * cos ( lat );
dot = DotProduct(n, shadevector);
if (dot < 0.0) //bizzare maths guessed by mh
dot = 1.0 + dot * (13.0 / 44.0);
else
dot = 1.0 + dot;
vc[i][0] = dot * lightcolor[0];
vc[i][1] = dot * lightcolor[1];
vc[i][2] = dot * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, vc);
}
}
else
{
if (shading)
{
for (i = 0; i < paliashdr->numverts_vbo; i++)
{
vec3_t n;
float dot;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = (float)verts2[i].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)verts2[i].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
n[0] = cos ( lng ) * sin ( lat );
n[1] = sin ( lng ) * sin ( lat );
n[2] = cos ( lat );
dot = DotProduct(n, shadevector);
if (dot < 0.0) //bizzare maths guessed by mh
dot = 1.0 + dot * (13.0 / 44.0);
else
dot = 1.0 + dot;
vc[i][0] = dot * lightcolor[0];
vc[i][1] = dot * lightcolor[1];
vc[i][2] = dot * lightcolor[2];
vc[i][3] = entalpha;
}
glEnableClientState(GL_COLOR_ARRAY);
GL_BindBuffer (GL_ARRAY_BUFFER, 0);
glColorPointer(4, GL_FLOAT, 0, vc);
}
GL_BindBuffer (GL_ARRAY_BUFFER, currententity->model->meshvbo);
glVertexPointer(3, GL_SHORT, sizeof (meshxyz_md3_t), GLARB_GetXYZOffset_MD3 (paliashdr, lerpdata.pose2));
}
}
break;
}
// set textures