Upload the normals with the vertex data.

Not all hardware can access a texture sampler from the vertex shader, and I
don't want multiple paths this early in the game. Now, vertex normals are
uploaded as shorts. Should be 14 bytes per vertex (was 10, could have been
8 if I had put the normal index with the vertex rather than st).
This commit is contained in:
Bill Currie 2012-01-04 09:42:00 +09:00
parent fea7acd871
commit add5440ad1
4 changed files with 45 additions and 67 deletions

View file

@ -32,8 +32,9 @@
#define __QF_GLSL_qf_alias_h
typedef struct aliasvrt_s {
short st[2];
short normal[3];
byte vertex[3];
short stn[3];
} aliasvrt_t;
void R_InitAlias (void);

View file

@ -50,6 +50,12 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
#include "QF/GLSL/qf_alias.h"
#include "QF/GLSL/qf_textures.h"
#include "r_shared.h"
static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
#include "anorms.h"
};
void *
Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc)
@ -141,16 +147,18 @@ Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s,
for (j = 0; j < hdr->mdl.numverts; j++) {
pv = &poseverts[i][j];
VectorCopy (pv->v, verts[pose + j].vertex);
VectorSet (st[j].s, st[j].t, pv->lightnormalindex,
verts[pose + j].stn);
verts[pose + j].st[0] = st[j].s;
verts[pose + j].st[1] = st[j].t;
VectorScale (vertex_normals[pv->lightnormalindex], 32767,
verts[pose + j].normal);
// 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;
verts[pose + indexmap[j]].stn[1] = st[indexmap[j]].t;
verts[pose + indexmap[j]].st[0] = st[indexmap[j]].s;
verts[pose + indexmap[j]].st[1] = st[indexmap[j]].t;
}
}
}

View file

@ -51,10 +51,6 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
#include "r_local.h"
static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
#include "anorms.h"
};
static const char quakemdl_vert[] =
#include "quakemdl.vc"
;
@ -65,12 +61,12 @@ static const char quakemdl_frag[] =
static struct {
int program;
shaderparam_t normals;
shaderparam_t mvp_matrix;
shaderparam_t norm_matrix;
shaderparam_t skin_size;
shaderparam_t color;
shaderparam_t stn;
shaderparam_t st;
shaderparam_t normal;
shaderparam_t vertex;
shaderparam_t palette;
shaderparam_t colormap;
@ -80,12 +76,12 @@ static struct {
shaderparam_t lightvec;
} quake_mdl = {
0,
{"normals", 1},
{"mvp_mat", 1},
{"norm_mat", 1},
{"skin_size", 1},
{"vcolor", 0},
{"stn", 0},
{"vst", 0},
{"vnormal", 0},
{"vertex", 0},
{"palette", 1},
{"colormap", 1},
@ -95,49 +91,24 @@ static struct {
{"lightvec", 1},
};
static int vnorms_tex;
static mat4_t alias_vp;
static void
build_normals_texture (void)
{
vec3_t temp;
static const vec3_t one = { 1, 1, 1};
unsigned short norm[3];
int i, j;
byte *data;
data = malloc (NUMVERTEXNORMALS * 3 * 2);
for (i = 0; i < NUMVERTEXNORMALS; i++) {
VectorAdd (vertex_normals[i], one, temp); // temp is 0.0 .. 2.0
VectorScale (temp, 32767.5, norm); // norm is 0 .. 65535
for (j = 0; j < 3; j++) {
data[i * 6 + 0 + j] = norm[j] >> 8;
data[i * 6 + 3 + j] = norm[j] & 0xff;
}
}
vnorms_tex = GL_LoadRGBTexture ("vertex_normals", 2, NUMVERTEXNORMALS,
data);
free (data);
}
VISIBLE void
R_InitAlias (void)
{
int vert;
int frag;
build_normals_texture ();
vert = GL_CompileShader ("quakemdl.vert", quakemdl_vert, GL_VERTEX_SHADER);
frag = GL_CompileShader ("quakemdl.frag", quakemdl_frag,
GL_FRAGMENT_SHADER);
quake_mdl.program = GL_LinkProgram ("quakemdl", vert, frag);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.normals);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.mvp_matrix);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.norm_matrix);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.skin_size);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.color);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.stn);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.st);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.normal);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.vertex);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.palette);
GL_ResolveShaderParam (quake_mdl.program, &quake_mdl.colormap);
@ -179,10 +150,10 @@ R_DrawAlias (void)
{
#ifdef TETRAHEDRON
static aliasvrt_t debug_verts[] = {
{{0,0,0},{0,0,0}},
{{255,255,0},{0,300,0}},
{{0,255,255},{300,300,0}},
{{255,0,255},{300,0,0}},
{{ 0, 0}, {-18918,-18918,-18918}, { 0, 0, 0}},
{{ 0,300}, { 18918, 18918,-18918}, {255,255, 0}},
{{300,300}, {-18918, 18918, 18918}, { 0,255,255}},
{{300, 0}, { 18918,-18918, 18918}, {255, 0,255}},
};
static GLushort debug_indices[] = {
0, 1, 2,
@ -251,17 +222,23 @@ R_DrawAlias (void)
qfglVertexAttribPointer (quake_mdl.vertex.location, 3, GL_UNSIGNED_BYTE,
0, sizeof (aliasvrt_t),
(byte *) pose + field_offset (aliasvrt_t, vertex));
qfglVertexAttribPointer (quake_mdl.stn.location, 3, GL_SHORT,
qfglVertexAttribPointer (quake_mdl.normal.location, 3, GL_SHORT,
0, sizeof (aliasvrt_t),
(byte *) pose + field_offset (aliasvrt_t, stn));
(byte *) pose + field_offset (aliasvrt_t, normal));
qfglVertexAttribPointer (quake_mdl.st.location, 2, GL_SHORT,
0, sizeof (aliasvrt_t),
(byte *) pose + field_offset (aliasvrt_t, st));
qfglDrawElements (GL_TRIANGLES, 3 * hdr->mdl.numtris, GL_UNSIGNED_SHORT, 0);
#else
qfglVertexAttribPointer (quake_mdl.vertex.location, 3, GL_UNSIGNED_BYTE,
0, sizeof (aliasvrt_t),
&debug_verts[0].vertex);
qfglVertexAttribPointer (quake_mdl.stn.location, 3, GL_SHORT,
qfglVertexAttribPointer (quake_mdl.st.location, 3, GL_SHORT,
0, sizeof (aliasvrt_t),
&debug_verts[0].stn);
&debug_verts[0].normal);
qfglVertexAttribPointer (quake_mdl.st.location, 3, GL_SHORT,
0, sizeof (aliasvrt_t),
&debug_verts[0].st);
qfglDrawElements (GL_TRIANGLES,
sizeof (debug_indices) / sizeof (debug_indices[0]),
GL_UNSIGNED_SHORT, debug_indices);
@ -277,21 +254,17 @@ R_AliasBegin (void)
qfglUseProgram (quake_mdl.program);
qfglEnableVertexAttribArray (quake_mdl.vertex.location);
qfglEnableVertexAttribArray (quake_mdl.stn.location);
qfglEnableVertexAttribArray (quake_mdl.normal.location);
qfglEnableVertexAttribArray (quake_mdl.st.location);
qfglDisableVertexAttribArray (quake_mdl.color.location);
qfglUniform1i (quake_mdl.normals.location, 1);
qfglUniform1i (quake_mdl.colormap.location, 1);
qfglActiveTexture (GL_TEXTURE0 + 1);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, vnorms_tex);
qfglUniform1i (quake_mdl.colormap.location, 2);
qfglActiveTexture (GL_TEXTURE0 + 2);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, glsl_colormap);
qfglUniform1i (quake_mdl.palette.location, 3);
qfglActiveTexture (GL_TEXTURE0 + 3);
qfglUniform1i (quake_mdl.palette.location, 2);
qfglActiveTexture (GL_TEXTURE0 + 2);
qfglEnable (GL_TEXTURE_2D);
qfglBindTexture (GL_TEXTURE_2D, glsl_palette);
@ -307,7 +280,8 @@ R_AliasEnd (void)
qfglBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
qfglDisableVertexAttribArray (quake_mdl.vertex.location);
qfglDisableVertexAttribArray (quake_mdl.stn.location);
qfglDisableVertexAttribArray (quake_mdl.normal.location);
qfglDisableVertexAttribArray (quake_mdl.st.location);
qfglActiveTexture (GL_TEXTURE0 + 0);
qfglDisable (GL_TEXTURE_2D);

View file

@ -1,10 +1,10 @@
uniform sampler2D normals;
uniform mat4 mvp_mat;
uniform mat3 norm_mat;
uniform vec2 skin_size;
attribute vec4 vcolor;
attribute vec3 stn;
attribute vec2 vst;
attribute vec3 vnormal;
attribute vec3 vertex;
varying vec3 normal;
@ -14,13 +14,8 @@ varying vec4 color;
void
main (void)
{
float nind;
vec3 norma, normb;
gl_Position = mvp_mat * vec4 (vertex, 1.0);
st = stn.st / skin_size;
nind = stn.p / 162.0;
norma = texture2D (normals, vec2 (0.0, nind)).xyz;
normb = texture2D (normals, vec2 (1.0, nind)).xyz;
normal = norm_mat * (2.0 * norma + normb / 128.0 - vec3 (1.0, 1.0, 1.0));
st = vst / skin_size;
normal = norm_mat * vnormal;
color = vcolor;
}