mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Finish alias skin loading and load vertex data into GL.
This commit is contained in:
parent
f18cd65526
commit
f3884c659c
3 changed files with 157 additions and 12 deletions
41
include/QF/GLSL/qf_alias.h
Normal file
41
include/QF/GLSL/qf_alias.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
qf_alias.h
|
||||
|
||||
GLSL specific alias model stuff
|
||||
|
||||
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2012/1/1
|
||||
|
||||
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
|
||||
|
||||
$Id$
|
||||
*/
|
||||
#ifndef __QF_GLSL_qf_alias_h
|
||||
#define __QF_GLSL_qf_alias_h
|
||||
|
||||
typedef struct aliasvrt_s {
|
||||
vec3_t vertex;
|
||||
vec3_t stn;
|
||||
} aliasvrt_t;
|
||||
|
||||
void R_InitAlias (void);
|
||||
|
||||
#endif//__QF_GLSL_qf_alias_h
|
|
@ -16,8 +16,8 @@ nobase_pkginclude_HEADERS = \
|
|||
GL/qf_rlight.h GL/qf_rmain.h GL/qf_rsurf.h GL/qf_sky.h GL/qf_textures.h \
|
||||
GL/qf_vid.h GL/types.h \
|
||||
\
|
||||
GLSL/defines.h GLSL/funcs.h GLSL/qf_funcs_list.h GLSL/qf_textures.h \
|
||||
GLSL/qf_vid.h GLSL/types.h \
|
||||
GLSL/defines.h GLSL/funcs.h GLSL/qf_alias.h GLSL/qf_funcs_list.h \
|
||||
GLSL/qf_textures.h GLSL/qf_vid.h GLSL/types.h \
|
||||
\
|
||||
plugin/cd.h plugin/console.h plugin/general.h plugin/input.h \
|
||||
plugin/snd_output.h plugin/snd_render.h
|
||||
|
|
|
@ -43,25 +43,31 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "QF/model.h"
|
||||
#include "QF/GL/defines.h"
|
||||
#include "QF/GL/funcs.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/GLSL/defines.h"
|
||||
#include "QF/GLSL/funcs.h"
|
||||
#include "QF/GLSL/qf_alias.h"
|
||||
#include "QF/GLSL/qf_textures.h"
|
||||
|
||||
void *
|
||||
Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group,
|
||||
maliasskindesc_t *skindesc)
|
||||
{
|
||||
byte *tskin;
|
||||
GLuint tnum;
|
||||
const char *name;
|
||||
int w, h;
|
||||
|
||||
w = pheader->mdl.skinwidth;
|
||||
h = pheader->mdl.skinheight;
|
||||
tskin = malloc (skinsize);
|
||||
memcpy (tskin, skin, skinsize);
|
||||
Mod_FloodFillSkin (tskin, pheader->mdl.skinwidth, pheader->mdl.skinheight);
|
||||
qfglGenTextures (1, &tnum);
|
||||
skindesc->texnum = tnum;
|
||||
qfglBindTexture (GL_TEXTURE_2D, skindesc->texnum);
|
||||
qfglTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
pheader->mdl.skinwidth, pheader->mdl.skinheight,
|
||||
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, tskin);
|
||||
Mod_FloodFillSkin (tskin, w, h);
|
||||
if (group)
|
||||
name = va ("%s_%i_%i", loadmodel->name, snum, gnum);
|
||||
else
|
||||
name = va ("%s_%i", loadmodel->name, snum);
|
||||
skindesc->texnum = GL_LoadQuakeTexture (name, w, h, tskin);
|
||||
free (tskin);
|
||||
return skin + skinsize;
|
||||
}
|
||||
|
@ -80,4 +86,102 @@ void
|
|||
Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s,
|
||||
int extra)
|
||||
{
|
||||
mtriangle_t *tris;
|
||||
stvert_t *st;
|
||||
aliasvrt_t *verts;
|
||||
trivertx_t *pv;
|
||||
int *indexmap;
|
||||
GLushort *indices;
|
||||
GLuint bnum[2];
|
||||
int vertexsize, indexsize;
|
||||
int numverts;
|
||||
int numtris;
|
||||
int i, j;
|
||||
int pose;
|
||||
float w, h;
|
||||
|
||||
numverts = hdr->mdl.numverts;
|
||||
numtris = hdr->mdl.numtris;
|
||||
w = hdr->mdl.skinwidth;
|
||||
h = hdr->mdl.skinheight;
|
||||
|
||||
// copy triangles before editing them
|
||||
tris = malloc (numtris * sizeof (mtriangle_t));
|
||||
memcpy (tris, triangles, numtris * sizeof (mtriangle_t));
|
||||
|
||||
// initialize indexmap to -1 (unduplicated). any other value indicates
|
||||
// both that the vertex has been duplicated and the index of the
|
||||
// duplicate vertex.
|
||||
indexmap = malloc (numverts * sizeof (int));
|
||||
memset (indexmap, -1, numverts * sizeof (int));
|
||||
|
||||
// copy stverts. need space for duplicates
|
||||
st = malloc (2 * numverts * sizeof (stvert_t));
|
||||
memcpy (st, stverts, numverts * sizeof (stvert_t));
|
||||
|
||||
// check for onseam verts, and duplicate any that are associated with
|
||||
// back-facing triangles. the s coordinate is shifted right by half
|
||||
// the skin width.
|
||||
for (i = 0; i < numtris; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
int vind = tris[i].vertindex[j];
|
||||
if (st[vind].onseam && !tris[i].facesfront) {
|
||||
if (indexmap[vind] == -1) {
|
||||
st[numverts] = st[vind];
|
||||
st[numverts].s += hdr->mdl.skinwidth / 2;
|
||||
indexmap[vind] = numverts++;
|
||||
}
|
||||
tris[i].vertindex[j] = indexmap[vind];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we now know exactly how many vertices we need, so built the vertex
|
||||
// array
|
||||
vertexsize = hdr->numposes * numverts * sizeof (aliasvrt_t);
|
||||
verts = malloc (vertexsize);
|
||||
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);
|
||||
VectorSet (st[j].s / w, st[j].t / h, pv->lightnormalindex,
|
||||
verts[pose + j].stn);
|
||||
// duplicate any verts that are marked for duplication by the
|
||||
// stvert setup, using the modified st coordinates
|
||||
if (indexmap[j] != -1) {
|
||||
// the vertex position and normal are duplicated, only s and t
|
||||
// are not (and really, only s, but this feels cleaner)
|
||||
verts[pose + indexmap[j]] = verts[pose + j];
|
||||
verts[pose + indexmap[j]].stn[0] = st[indexmap[j]].s / w;
|
||||
verts[pose + indexmap[j]].stn[1] = st[indexmap[j]].t / h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finished with st and indexmap
|
||||
free (st);
|
||||
free (indexmap);
|
||||
|
||||
// now build the indices for DrawElements
|
||||
indexsize = 3 * numtris * sizeof (GLushort);
|
||||
indices = malloc (indexsize);
|
||||
for (i = 0; i < numtris; i++)
|
||||
VectorCopy (tris[i].vertindex, indices + 3 * i);
|
||||
|
||||
// finished with tris
|
||||
free (tris);
|
||||
|
||||
// load the vertex data and indices into GL
|
||||
qfglGenBuffers (2, bnum);
|
||||
hdr->posedata = bnum[0];
|
||||
hdr->commands = bnum[1];
|
||||
qfglBindBuffer (GL_ARRAY_BUFFER, hdr->posedata);
|
||||
qfglBindBuffer (GL_ELEMENT_ARRAY_BUFFER, hdr->commands);
|
||||
qfglBufferData (GL_ARRAY_BUFFER, vertexsize, verts, GL_STATIC_DRAW);
|
||||
qfglBufferData (GL_ELEMENT_ARRAY_BUFFER, indexsize, indices,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// all done
|
||||
free (verts);
|
||||
free (indices);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue