Attempt to render iqm models.

Things are a right mess (segfaults, invalid accesses on load, etc), but
hey, it's a start :)
This commit is contained in:
Bill Currie 2012-05-11 15:26:34 +09:00
parent 15fd3be73a
commit 9c69404163
3 changed files with 113 additions and 17 deletions

View file

@ -63,9 +63,18 @@ static const char iqm_frag[] =
#include "iqm.fc"
;
typedef struct {
shaderparam_t position;
shaderparam_t color;
} lightpar_t;
#define MAX_IQM_LIGHTS 8
#define MAX_IQM_BONES 80
static struct {
int program;
shaderparam_t mvp_matrix;
shaderparam_t norm_matrix;
shaderparam_t bonemats;
shaderparam_t vcolor;
shaderparam_t vweights;
@ -74,10 +83,14 @@ static struct {
shaderparam_t vtangent;
shaderparam_t vnormal;
shaderparam_t position;
lightpar_t lights[MAX_IQM_LIGHTS];
shaderparam_t texture;
shaderparam_t normalmap;
shaderparam_t fog;
} iqm_shader = {
0,
{"mvp_mat", 1},
{"norm_mat", 1},
{"bonemats", 1},
{"vcolor", 0},
{"vweights", 0},
@ -86,6 +99,18 @@ static struct {
{"vtangent", 0},
{"vnormal", 0},
{"position", 0},
{
{{"lights[0].position", 1}, {"lights[0].color", 1}},
{{"lights[1].position", 1}, {"lights[1].color", 1}},
{{"lights[2].position", 1}, {"lights[2].color", 1}},
{{"lights[3].position", 1}, {"lights[3].color", 1}},
{{"lights[4].position", 1}, {"lights[4].color", 1}},
{{"lights[5].position", 1}, {"lights[5].color", 1}},
{{"lights[6].position", 1}, {"lights[6].color", 1}},
{{"lights[7].position", 1}, {"lights[7].color", 1}},
},
{"texture", 1},
{"normalmap", 1},
{"fog", 1},
};
@ -111,11 +136,13 @@ glsl_R_InitIQM (void)
{
int vert;
int frag;
int i;
vert = GLSL_CompileShader ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
frag = GLSL_CompileShader ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
iqm_shader.program = GLSL_LinkProgram ("iqm", vert, frag);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.mvp_matrix);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.norm_matrix);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.bonemats);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vcolor);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vweights);
@ -124,6 +151,14 @@ glsl_R_InitIQM (void)
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vtangent);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vnormal);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.position);
for (i = 0; i < MAX_IQM_LIGHTS; i++) {
GLSL_ResolveShaderParam (iqm_shader.program,
&iqm_shader.lights[i].position);
GLSL_ResolveShaderParam (iqm_shader.program,
&iqm_shader.lights[i].color);
}
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.texture);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.normalmap);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.fog);
}
@ -146,7 +181,8 @@ set_arrays (iqm_t *iqm)
qfeglEnableVertexAttribArray (attr->attr->location);
qfeglVertexAttribPointer (attr->attr->location, attr->size,
attr->type, attr->normalized, iqm->stride,
(byte *) 0 + va->offset);
iqm->vertices + va->offset);
//(byte *) 0 + va->offset);
}
while (j <= IQM_COLOR)
qfeglDisableVertexAttribArray (vertex_attribs[j++].attr->location);
@ -155,11 +191,66 @@ set_arrays (iqm_t *iqm)
void
glsl_R_DrawIQM (void)
{
static quat_t color = { 1, 1, 1, 1};
entity_t *ent = currententity;
model_t *model = ent->model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
dlight_t **lights;
int i;
vec_t norm_mat[9];
mat4_t mvp_mat;
float blend;
iqmframe_t *frame;
Sys_MaskPrintf (SYS_GLSL, "glsl_R_DrawIQM\n");
lights = R_FindNearLights (ent->origin, MAX_IQM_LIGHTS);
// we need only the rotation for normals.
VectorCopy (ent->transform + 0, norm_mat + 0);
VectorCopy (ent->transform + 4, norm_mat + 3);
VectorCopy (ent->transform + 8, norm_mat + 6);
Mat4Mult (iqm_vp, ent->transform, mvp_mat);
blend = R_EntityBlend (ent, ent->frame, 0.1);
frame = malloc (iqm->num_joints * sizeof (iqmframe_t));
for (i = 0; i < iqm->num_joints; i++) {
iqmframe_t *f1 = iqm->frames[ent->pose1];
iqmframe_t *f2 = iqm->frames[ent->pose2];
DualQuatBlend (f1->rt, f2->rt, blend, frame[i].rt);
QuatBlend (f1->shear, f2->shear, blend, frame[i].shear);
QuatBlend (f1->scale, f2->scale, blend, frame[i].scale);
}
for (i = 0; i < MAX_IQM_LIGHTS; i++) {
quat_t val;
lightpar_t *l = &iqm_shader.lights[i];
if (!lights[i])
break;
VectorCopy (lights[i]->origin, val);
val[3] = lights[i]->radius;
qfeglUniform4fv (l->position.location, 1, val);
qfeglUniform4fv (l->color.location, 1, lights[i]->color);
}
for (; i < MAX_IQM_LIGHTS; i++) {
lightpar_t *l = &iqm_shader.lights[i];
qfeglUniform4fv (l->position.location, 1, quat_origin);
qfeglUniform4fv (l->color.location, 1, quat_origin);
}
free (lights);
qfeglUniformMatrix4fv (iqm_shader.mvp_matrix.location, 1, false, mvp_mat);
qfeglUniformMatrix3fv (iqm_shader.norm_matrix.location, 1, false,
norm_mat);
qfeglUniformMatrix4fv (iqm_shader.bonemats.location, iqm->num_joints,
false, (float *) frame);
qfeglVertexAttrib4fv (iqm_shader.vcolor.location, color);
set_arrays (iqm);
for (i = 0; i < iqm->num_meshes; i++) {
qfeglDrawElements (GL_TRIANGLES, 3 * iqm->meshes[i].num_triangles,
GL_UNSIGNED_SHORT,
iqm->elements + 3 * iqm->meshes[i].first_triangle);
}
}
// All iqm models are drawn in a batch, so avoid thrashing the gl state

View file

@ -1,6 +1,10 @@
struct light {
vec4 position; // xyz = pos, w = strength
vec4 color; // rgb. a = ?
};
uniform sampler2D texture;
uniform sampler2D normalmap;
uniform vec4 lights[8];
uniform light lights[8];
uniform vec4 fog;
varying vec3 bitangent;
@ -29,28 +33,29 @@ vec3
calc_light (vec3 n, int ind)
{
vec3 d;
light l = lights[ind];
d = lights[ind].xyz - gl_FragCoord.xyz;
return vec3 (lights[ind].w * dot (d, n) / dot (d, d));
d = l.position.xyz - gl_FragCoord.xyz;
return l.color.rgb * (l.position.w * dot (d, n) / dot (d, d));
}
void
main (void)
{
mat3 tbn = mat3 (tangent, bitangent, normal);
vec3 norm, light;
vec3 norm, l;
vec4 col;
norm = texture2D (normalmap, st).xyz;
norm = tbn * norm;
light += calc_light (norm, 0);
light += calc_light (norm, 1);
light += calc_light (norm, 2);
light += calc_light (norm, 3);
light += calc_light (norm, 4);
light += calc_light (norm, 5);
light += calc_light (norm, 6);
light += calc_light (norm, 7);
col = texture2D (texture, st) * color * vec4 (light, 1.0);
l += calc_light (norm, 0);
l += calc_light (norm, 1);
l += calc_light (norm, 2);
l += calc_light (norm, 3);
l += calc_light (norm, 4);
l += calc_light (norm, 5);
l += calc_light (norm, 6);
l += calc_light (norm, 7);
col = texture2D (texture, st) * color * vec4 (l, 1.0);
gl_FragColor = fogBlend (col);
}

View file

@ -1,4 +1,5 @@
uniform mat4 mvp_mat;
uniform mat3 norm_mat;
uniform mat4 bonemats[80];
attribute vec4 vcolor;
attribute vec4 vweights;
@ -49,9 +50,8 @@ main (void)
t = vtangent.xyz;
t += 2.0 * cross (q0.xyz, cross (q0.xyz, t) + q0.w * t);
gl_Position = mvp_mat * vec4 (v, 1.0);
mat3 rot = mat3 (mvp_mat[0].xyz, mvp_mat[1].xyz, mvp_mat[3].xyz);
normal = rot * n;
tangent = rot * t;
normal = norm_mat * n;
tangent = norm_mat * t;
bitangent = cross (normal, tangent) * vtangent.w;
color = vcolor;
st = texcoord;