mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +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_CFLAGS= @PREFER_PIC@
|
||||||
AM_CPPFLAGS= -I$(top_srcdir)/include $(GLX_CFLAGS)
|
AM_CPPFLAGS= -I$(top_srcdir)/include $(GLX_CFLAGS)
|
||||||
|
|
||||||
shader_src= quakeforge.glsl \
|
shader_src= quakeforge.glsl
|
||||||
iqm.frag iqm.vert
|
shader_gen= quakeforge.slc
|
||||||
shader_gen= quakeforge.slc \
|
|
||||||
iqm.fc iqm.vc
|
|
||||||
|
|
||||||
glsl_src = \
|
glsl_src = \
|
||||||
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_iqm.c glsl_lightmap.c \
|
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"
|
#include "r_internal.h"
|
||||||
|
|
||||||
static const char iqm_vert[] =
|
static const char *iqm_vert_effects[] =
|
||||||
#include "iqm.vc"
|
{
|
||||||
;
|
"QuakeForge.Math.quaternion",
|
||||||
|
"QuakeForge.Vertex.iqm",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
static const char iqm_frag[] =
|
static const char *iqm_frag_effects[] =
|
||||||
#include "iqm.fc"
|
{
|
||||||
;
|
"QuakeForge.Fragment.fog",
|
||||||
|
"QuakeForge.Fragment.iqm",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
shaderparam_t position;
|
shaderparam_t position;
|
||||||
|
@ -136,12 +142,15 @@ static mat4_t iqm_vp;
|
||||||
void
|
void
|
||||||
glsl_R_InitIQM (void)
|
glsl_R_InitIQM (void)
|
||||||
{
|
{
|
||||||
|
shader_t *vert_shader, *frag_shader;
|
||||||
int vert;
|
int vert;
|
||||||
int frag;
|
int frag;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vert = GLSL_CompileShaderS ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
|
vert_shader = GLSL_BuildShader (iqm_vert_effects);
|
||||||
frag = GLSL_CompileShaderS ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
|
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);
|
iqm_shader.program = GLSL_LinkProgram ("iqm", vert, frag);
|
||||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.mvp_matrix);
|
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.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.texture);
|
||||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.normalmap);
|
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.normalmap);
|
||||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.fog);
|
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.fog);
|
||||||
|
GLSL_FreeShader (vert_shader);
|
||||||
|
GLSL_FreeShader (frag_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
vec3
|
||||||
qmult (vec4 q, vec3 v)
|
qmult (vec4 q, vec3 v)
|
||||||
{
|
{
|
||||||
float qc = q.w;
|
float qs = q.w;
|
||||||
vec3 qv = q.xyz;
|
vec3 qv = q.xyz;
|
||||||
vec3 t = cross (qv, v);
|
vec3 t = cross (qv, v);
|
||||||
return (qs * qs) * v + 2.0 * qs * t + dot (qv, v) * qv + cross (qv, t);
|
return (qs * qs) * v + 2.0 * qs * t + dot (qv, v) * qv + cross (qv, t);
|
||||||
|
@ -431,3 +431,123 @@ main (void)
|
||||||
discard;
|
discard;
|
||||||
gl_FragColor = palettedColor (pix) * color;
|
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