mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
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:
parent
15fd3be73a
commit
9c69404163
3 changed files with 113 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue