mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Use the new shader system for iqm models.
This commit is contained in:
parent
385175ca65
commit
57d2198140
5 changed files with 142 additions and 162 deletions
|
@ -3,10 +3,8 @@ AUTOMAKE_OPTIONS= foreign
|
|||
AM_CFLAGS= @PREFER_PIC@
|
||||
AM_CPPFLAGS= -I$(top_srcdir)/include $(GLX_CFLAGS)
|
||||
|
||||
shader_src= quakeforge.glsl \
|
||||
iqm.frag iqm.vert
|
||||
shader_gen= quakeforge.slc \
|
||||
iqm.fc iqm.vc
|
||||
shader_src= quakeforge.glsl
|
||||
shader_gen= quakeforge.slc
|
||||
|
||||
glsl_src = \
|
||||
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_iqm.c glsl_lightmap.c \
|
||||
|
|
|
@ -55,13 +55,19 @@
|
|||
|
||||
#include "r_internal.h"
|
||||
|
||||
static const char iqm_vert[] =
|
||||
#include "iqm.vc"
|
||||
;
|
||||
static const char *iqm_vert_effects[] =
|
||||
{
|
||||
"QuakeForge.Math.quaternion",
|
||||
"QuakeForge.Vertex.iqm",
|
||||
0
|
||||
};
|
||||
|
||||
static const char iqm_frag[] =
|
||||
#include "iqm.fc"
|
||||
;
|
||||
static const char *iqm_frag_effects[] =
|
||||
{
|
||||
"QuakeForge.Fragment.fog",
|
||||
"QuakeForge.Fragment.iqm",
|
||||
0
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
shaderparam_t position;
|
||||
|
@ -136,12 +142,15 @@ static mat4_t iqm_vp;
|
|||
void
|
||||
glsl_R_InitIQM (void)
|
||||
{
|
||||
shader_t *vert_shader, *frag_shader;
|
||||
int vert;
|
||||
int frag;
|
||||
int i;
|
||||
|
||||
vert = GLSL_CompileShaderS ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShaderS ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
|
||||
vert_shader = GLSL_BuildShader (iqm_vert_effects);
|
||||
frag_shader = GLSL_BuildShader (iqm_frag_effects);
|
||||
vert = GLSL_CompileShader ("iqm.vert", vert_shader, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("iqm.frag", frag_shader, 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);
|
||||
|
@ -163,6 +172,8 @@ glsl_R_InitIQM (void)
|
|||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.texture);
|
||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.normalmap);
|
||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.fog);
|
||||
GLSL_FreeShader (vert_shader);
|
||||
GLSL_FreeShader (frag_shader);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
struct light {
|
||||
vec4 position; // xyz = pos, w = strength
|
||||
vec4 color; // rgb. a = ?
|
||||
};
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D normalmap;
|
||||
uniform vec3 ambient;
|
||||
uniform light lights[8];
|
||||
uniform vec4 fog;
|
||||
|
||||
varying vec3 position;
|
||||
varying vec3 bitangent;
|
||||
varying vec3 tangent;
|
||||
varying vec3 normal;
|
||||
varying vec2 st;
|
||||
varying vec4 color;
|
||||
|
||||
float
|
||||
sqr (float x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
vec4
|
||||
fogBlend (vec4 color)
|
||||
{
|
||||
float f;
|
||||
vec4 fog_color = vec4 (fog.rgb, 1.0);
|
||||
|
||||
f = exp (-sqr (fog.a * gl_FragCoord.z / gl_FragCoord.w));
|
||||
return vec4 (mix (fog_color.rgb, color.rgb, f), color.a);
|
||||
}
|
||||
|
||||
vec3
|
||||
calc_light (vec3 n, int ind)
|
||||
{
|
||||
vec3 d;
|
||||
light l = lights[ind];
|
||||
float mag;
|
||||
|
||||
d = l.position.xyz - position;
|
||||
mag = dot (d, n);
|
||||
mag = max (0.0, mag);
|
||||
return l.color.rgb * (l.position.w * mag / dot (d, d));
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
mat3 tbn = mat3 (tangent, bitangent, normal);
|
||||
vec3 norm, l;
|
||||
vec4 col;
|
||||
|
||||
norm = (texture2D (normalmap, st).xyz - vec3(0.5)) * 2.0;
|
||||
norm = tbn * norm;
|
||||
l = ambient;
|
||||
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,82 +0,0 @@
|
|||
uniform mat4 mvp_mat;
|
||||
uniform mat3 norm_mat;
|
||||
uniform mat4 bonemats[80];
|
||||
attribute vec4 vcolor;
|
||||
attribute vec4 vweights;
|
||||
attribute vec4 vbones;
|
||||
attribute vec4 vtangent;
|
||||
attribute vec3 vnormal;
|
||||
attribute vec2 texcoord;
|
||||
attribute vec3 vposition;
|
||||
|
||||
varying vec3 position;
|
||||
varying vec3 bitangent;
|
||||
varying vec3 tangent;
|
||||
varying vec3 normal;
|
||||
varying vec2 st;
|
||||
varying vec4 color;
|
||||
|
||||
vec3
|
||||
qmult (vec4 q, vec3 v)
|
||||
{
|
||||
float qs = q.w;
|
||||
vec3 qv = q.xyz;
|
||||
vec3 t = cross (qv, v);
|
||||
return (qs * qs) * v + 2.0 * qs * t + dot (qv, v) * qv + cross (qv, t);
|
||||
}
|
||||
|
||||
vec3
|
||||
dqtrans (vec4 q0, vec4 qe)
|
||||
{//2.0 * (q0.w * qe.xyz - qe.w * q0.xyz - cross (qe.xyz, q0.xyz));
|
||||
float qs = q0.w, Ts = qe.w;
|
||||
vec3 qv = -q0.xyz, Tv = qe.xyz;
|
||||
|
||||
return 2.0 * (Ts * qv + qs * Tv + cross (Tv, qv));
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
mat4 m;
|
||||
vec4 q0, qe;
|
||||
vec3 sh, sc, tr, v, n, t;
|
||||
|
||||
m = bonemats[int (vbones.x)] * vweights.x;
|
||||
m += bonemats[int (vbones.y)] * vweights.y;
|
||||
m += bonemats[int (vbones.z)] * vweights.z;
|
||||
m += bonemats[int (vbones.w)] * vweights.w;
|
||||
#if 0
|
||||
q0 = m[0].yzwx; //swizzle for conversion betwen QF and GL
|
||||
qe = m[1].yzwx; //swizzle for conversion betwen QF and GL
|
||||
sh = m[2].xyz;
|
||||
sc = m[3].xyz;
|
||||
|
||||
// extract translation from dual quaternion
|
||||
tr = dqtrans (q0, qe);
|
||||
// apply rotation and translation
|
||||
v = qmult (q0, vposition) + tr;
|
||||
// apply shear
|
||||
v.z += v.y * sh.z + v.x * sh.y;
|
||||
v.y += v.x * sh.x;
|
||||
// apply scale
|
||||
v *= sc;
|
||||
// rotate normal (won't bother with shear or scale: not super accurate,
|
||||
// but probably good enough)
|
||||
n = qmult (q0, vnormal);
|
||||
// rotate tangent (won't bother with shear or scale: not super accurate,
|
||||
// but probably good enough)
|
||||
t = qmult (q0, vtangent.xyz);
|
||||
#else
|
||||
mat3 nm = mat3 (m[0].xyz, m[1].xyz, m[2].xyz);
|
||||
v = (m * vec4 (vposition, 1.0)).xyz;
|
||||
n = nm * vnormal;
|
||||
t = nm * vtangent.xyz;
|
||||
#endif
|
||||
position = v;
|
||||
normal = norm_mat * n;
|
||||
tangent = norm_mat * t;
|
||||
bitangent = cross (normal, tangent) * vtangent.w;
|
||||
color = vcolor;
|
||||
st = texcoord;
|
||||
gl_Position = mvp_mat * vec4 (position, 1.0);
|
||||
}
|
|
@ -8,7 +8,7 @@ const float E = 2.71828183;
|
|||
vec3
|
||||
qmult (vec4 q, vec3 v)
|
||||
{
|
||||
float qc = q.w;
|
||||
float qs = q.w;
|
||||
vec3 qv = q.xyz;
|
||||
vec3 t = cross (qv, v);
|
||||
return (qs * qs) * v + 2.0 * qs * t + dot (qv, v) * qv + cross (qv, t);
|
||||
|
@ -431,3 +431,123 @@ main (void)
|
|||
discard;
|
||||
gl_FragColor = palettedColor (pix) * color;
|
||||
}
|
||||
|
||||
-- Vertex.iqm
|
||||
|
||||
uniform mat4 mvp_mat;
|
||||
uniform mat3 norm_mat;
|
||||
uniform mat4 bonemats[80];
|
||||
attribute vec4 vcolor;
|
||||
attribute vec4 vweights;
|
||||
attribute vec4 vbones;
|
||||
attribute vec4 vtangent;
|
||||
attribute vec3 vnormal;
|
||||
attribute vec2 texcoord;
|
||||
attribute vec3 vposition;
|
||||
|
||||
varying vec3 position;
|
||||
varying vec3 bitangent;
|
||||
varying vec3 tangent;
|
||||
varying vec3 normal;
|
||||
varying vec2 st;
|
||||
varying vec4 color;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
mat4 m;
|
||||
vec4 q0, qe;
|
||||
vec3 sh, sc, tr, v, n, t;
|
||||
|
||||
m = bonemats[int (vbones.x)] * vweights.x;
|
||||
m += bonemats[int (vbones.y)] * vweights.y;
|
||||
m += bonemats[int (vbones.z)] * vweights.z;
|
||||
m += bonemats[int (vbones.w)] * vweights.w;
|
||||
#if 0
|
||||
q0 = m[0].yzwx; //swizzle for conversion betwen QF and GL
|
||||
qe = m[1].yzwx; //swizzle for conversion betwen QF and GL
|
||||
sh = m[2].xyz;
|
||||
sc = m[3].xyz;
|
||||
|
||||
// extract translation from dual quaternion
|
||||
tr = dqtrans (q0, qe);
|
||||
// apply rotation and translation
|
||||
v = qmult (q0, vposition) + tr;
|
||||
// apply shear
|
||||
v.z += v.y * sh.z + v.x * sh.y;
|
||||
v.y += v.x * sh.x;
|
||||
// apply scale
|
||||
v *= sc;
|
||||
// rotate normal (won't bother with shear or scale: not super accurate,
|
||||
// but probably good enough)
|
||||
n = qmult (q0, vnormal);
|
||||
// rotate tangent (won't bother with shear or scale: not super accurate,
|
||||
// but probably good enough)
|
||||
t = qmult (q0, vtangent.xyz);
|
||||
#else
|
||||
mat3 nm = mat3 (m[0].xyz, m[1].xyz, m[2].xyz);
|
||||
v = (m * vec4 (vposition, 1.0)).xyz;
|
||||
n = nm * vnormal;
|
||||
t = nm * vtangent.xyz;
|
||||
#endif
|
||||
position = v;
|
||||
normal = norm_mat * n;
|
||||
tangent = norm_mat * t;
|
||||
bitangent = cross (normal, tangent) * vtangent.w;
|
||||
color = vcolor;
|
||||
st = texcoord;
|
||||
gl_Position = mvp_mat * vec4 (position, 1.0);
|
||||
}
|
||||
|
||||
-- Fragment.iqm
|
||||
|
||||
struct light {
|
||||
vec4 position; // xyz = pos, w = strength
|
||||
vec4 color; // rgb. a = ?
|
||||
};
|
||||
uniform sampler2D texture;
|
||||
uniform sampler2D normalmap;
|
||||
uniform vec3 ambient;
|
||||
uniform light lights[8];
|
||||
|
||||
varying vec3 position;
|
||||
varying vec3 bitangent;
|
||||
varying vec3 tangent;
|
||||
varying vec3 normal;
|
||||
varying vec2 st;
|
||||
varying vec4 color;
|
||||
|
||||
vec3
|
||||
calc_light (vec3 n, int ind)
|
||||
{
|
||||
vec3 d;
|
||||
light l = lights[ind];
|
||||
float mag;
|
||||
|
||||
d = l.position.xyz - position;
|
||||
mag = dot (d, n);
|
||||
mag = max (0.0, mag);
|
||||
return l.color.rgb * (l.position.w * mag / dot (d, d));
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
mat3 tbn = mat3 (tangent, bitangent, normal);
|
||||
vec3 norm, l;
|
||||
vec4 col;
|
||||
|
||||
norm = (texture2D (normalmap, st).xyz - vec3(0.5)) * 2.0;
|
||||
norm = tbn * norm;
|
||||
l = ambient;
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue