mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
Update the trails code to use shader effects.
Trails was actually the reason I started that project. This is just cleanup after rebasing.
This commit is contained in:
parent
bb022bc4fc
commit
299f305453
5 changed files with 141 additions and 127 deletions
|
@ -3,8 +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 trail.frag trail.vert
|
shader_src= quakeforge.glsl
|
||||||
shader_gen= quakeforge.slc trail.fc trail.vc
|
shader_gen= quakeforge.slc
|
||||||
|
|
||||||
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 \
|
||||||
|
|
|
@ -107,13 +107,17 @@ static const char *particle_textured_frag_effects[] =
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char trail_vert[] =
|
static const char *particle_trail_vert_effects[] =
|
||||||
#include "trail.vc"
|
{
|
||||||
;
|
"QuakeForge.Vertex.particle.trail",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
static const char trail_frag[] =
|
static const char *particle_trail_frag_effects[] =
|
||||||
#include "trail.fc"
|
{
|
||||||
;
|
"QuakeForge.Fragment.particle.trail",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int program;
|
int program;
|
||||||
|
@ -190,9 +194,9 @@ typedef struct trailvtx_s {
|
||||||
float texoff;
|
float texoff;
|
||||||
} trailvtx_t;
|
} trailvtx_t;
|
||||||
|
|
||||||
static trail_t *free_trails;
|
static trail_t *trails_freelist;
|
||||||
static trail_t *active_trails;
|
static trail_t *trails_active;
|
||||||
static particle_t *free_points;
|
static particle_t *points_freelist;
|
||||||
|
|
||||||
static trail_t *
|
static trail_t *
|
||||||
new_trail (void)
|
new_trail (void)
|
||||||
|
@ -350,8 +354,10 @@ glsl_R_InitParticles (void)
|
||||||
GLSL_FreeShader (vert_shader);
|
GLSL_FreeShader (vert_shader);
|
||||||
GLSL_FreeShader (frag_shader);
|
GLSL_FreeShader (frag_shader);
|
||||||
|
|
||||||
vert = GLSL_CompileShader ("trail.vert", trail_vert, GL_VERTEX_SHADER);
|
vert_shader = GLSL_BuildShader (particle_trail_vert_effects);
|
||||||
frag = GLSL_CompileShader ("trail.frag", trail_frag, GL_FRAGMENT_SHADER);
|
frag_shader = GLSL_BuildShader (particle_trail_frag_effects);
|
||||||
|
vert = GLSL_CompileShader ("trail.vert", vert_shader, GL_VERTEX_SHADER);
|
||||||
|
frag = GLSL_CompileShader ("trail.frag", frag_shader, GL_FRAGMENT_SHADER);
|
||||||
trail.program = GLSL_LinkProgram ("trail", vert, frag);
|
trail.program = GLSL_LinkProgram ("trail", vert, frag);
|
||||||
GLSL_ResolveShaderParam (trail.program, &trail.proj);
|
GLSL_ResolveShaderParam (trail.program, &trail.proj);
|
||||||
GLSL_ResolveShaderParam (trail.program, &trail.view);
|
GLSL_ResolveShaderParam (trail.program, &trail.view);
|
||||||
|
@ -363,6 +369,8 @@ glsl_R_InitParticles (void)
|
||||||
GLSL_ResolveShaderParam (trail.program, &trail.barycentric);
|
GLSL_ResolveShaderParam (trail.program, &trail.barycentric);
|
||||||
GLSL_ResolveShaderParam (trail.program, &trail.texoff);
|
GLSL_ResolveShaderParam (trail.program, &trail.texoff);
|
||||||
GLSL_ResolveShaderParam (trail.program, &trail.smoke);
|
GLSL_ResolveShaderParam (trail.program, &trail.smoke);
|
||||||
|
GLSL_FreeShader (vert_shader);
|
||||||
|
GLSL_FreeShader (frag_shader);
|
||||||
|
|
||||||
memset (data, 0, sizeof (data));
|
memset (data, 0, sizeof (data));
|
||||||
qfeglGenTextures (1, &part_tex);
|
qfeglGenTextures (1, &part_tex);
|
||||||
|
@ -730,12 +738,12 @@ R_RocketTrail_trail (entity_t *ent)
|
||||||
|
|
||||||
if (!ent->trail) {
|
if (!ent->trail) {
|
||||||
ent->trail = new_trail ();
|
ent->trail = new_trail ();
|
||||||
ent->trail->next = active_trails;
|
ent->trail->next = trails_active;
|
||||||
ent->trail->prev = &active_trails;
|
ent->trail->prev = &trails_active;
|
||||||
ent->trail->owner = &ent->trail;
|
ent->trail->owner = &ent->trail;
|
||||||
if (active_trails)
|
if (trails_active)
|
||||||
active_trails->prev = &ent->trail->next;
|
trails_active->prev = &ent->trail->next;
|
||||||
active_trails = ent->trail;
|
trails_active = ent->trail;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy (ent->old_origin, old_origin);
|
VectorCopy (ent->old_origin, old_origin);
|
||||||
|
@ -1723,7 +1731,7 @@ count_points (int *num_verts, int *num_elements)
|
||||||
|
|
||||||
*num_verts = 0;
|
*num_verts = 0;
|
||||||
*num_elements = 0;
|
*num_elements = 0;
|
||||||
for (trail = active_trails; trail; trail = trail->next) {
|
for (trail = trails_active; trail; trail = trail->next) {
|
||||||
if (trail->num_points < 2)
|
if (trail->num_points < 2)
|
||||||
continue;
|
continue;
|
||||||
// +2 for an extra point at either end of the strip
|
// +2 for an extra point at either end of the strip
|
||||||
|
@ -1741,7 +1749,7 @@ build_verts (trailvtx_t *v, GLushort *e)
|
||||||
float bary[] = {0, 0, 1, 0, 0, 1, 0, 0};
|
float bary[] = {0, 0, 1, 0, 0, 1, 0, 0};
|
||||||
int bind = 0;
|
int bind = 0;
|
||||||
|
|
||||||
for (trail = active_trails; trail; trail = trail->next) {
|
for (trail = trails_active; trail; trail = trail->next) {
|
||||||
if (trail->num_points < 2)
|
if (trail->num_points < 2)
|
||||||
continue;
|
continue;
|
||||||
point = trail->points;
|
point = trail->points;
|
||||||
|
@ -1768,7 +1776,7 @@ expire_trails (void)
|
||||||
{
|
{
|
||||||
trail_t *trail, *next_trail;
|
trail_t *trail, *next_trail;
|
||||||
|
|
||||||
for (trail = active_trails; trail; trail = next_trail) {
|
for (trail = trails_active; trail; trail = next_trail) {
|
||||||
next_trail = trail->next;
|
next_trail = trail->next;
|
||||||
while (trail->points && trail->points->die <= vr_data.realtime) {
|
while (trail->points && trail->points->die <= vr_data.realtime) {
|
||||||
particle_t *point = trail->points;
|
particle_t *point = trail->points;
|
||||||
|
@ -1827,7 +1835,7 @@ draw_trails (void)
|
||||||
qfeglVertexAttribPointer (trail.texoff.location, 1, GL_FLOAT,
|
qfeglVertexAttribPointer (trail.texoff.location, 1, GL_FLOAT,
|
||||||
0, sizeof (trailvtx_t), &verts[0].texoff);
|
0, sizeof (trailvtx_t), &verts[0].texoff);
|
||||||
|
|
||||||
for (trl = active_trails; trl; trl = trl->next) {
|
for (trl = trails_active; trl; trl = trl->next) {
|
||||||
int count;
|
int count;
|
||||||
if (trl->num_points < 2)
|
if (trl->num_points < 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -551,3 +551,114 @@ main (void)
|
||||||
col = texture2D (texture, st) * color * vec4 (l, 1.0);
|
col = texture2D (texture, st) * color * vec4 (l, 1.0);
|
||||||
gl_FragColor = fogBlend (col);
|
gl_FragColor = fogBlend (col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Vertex.particle.trail
|
||||||
|
|
||||||
|
attribute vec4 last, current, next;
|
||||||
|
attribute vec3 barycentric;
|
||||||
|
attribute float texoff;
|
||||||
|
|
||||||
|
uniform mat4 proj, view;
|
||||||
|
uniform vec2 viewport;
|
||||||
|
uniform float width;
|
||||||
|
|
||||||
|
varying vec2 texcoord;
|
||||||
|
varying vec3 vBC;
|
||||||
|
|
||||||
|
vec4
|
||||||
|
transform (vec3 coord)
|
||||||
|
{
|
||||||
|
return proj * view * vec4 (coord, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2
|
||||||
|
project (vec4 coord)
|
||||||
|
{
|
||||||
|
vec3 device = coord.xyz / coord.w;
|
||||||
|
vec2 clip = (device * 0.5 + 0.5).xy;
|
||||||
|
return clip * viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4
|
||||||
|
unproject (vec2 screen, float z, float w)
|
||||||
|
{
|
||||||
|
vec2 clip = screen / viewport;
|
||||||
|
vec2 device = clip * 2.0 - 1.0;
|
||||||
|
return vec4 (device * w, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
estimateScale (vec3 position, vec2 sPosition)
|
||||||
|
{
|
||||||
|
vec4 view_pos = view * vec4 (position, 1.0);
|
||||||
|
vec4 scale_pos = view_pos - vec4 (normalize (view_pos.xy) * width,
|
||||||
|
0.0, 0.0);
|
||||||
|
vec2 screen_scale_pos = project (proj * scale_pos);
|
||||||
|
return distance (sPosition, screen_scale_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
vec2 t, n1, n2, n;
|
||||||
|
vec2 sLast = project (transform (last.xyz));
|
||||||
|
vec2 sNext = project (transform (next.xyz));
|
||||||
|
vec4 dCurrent = transform (current.xyz);
|
||||||
|
vec2 sCurrent = project (dCurrent);
|
||||||
|
float off = current.w;
|
||||||
|
|
||||||
|
texcoord = vec2 (texoff * 0.7, off * 0.5 + 0.5);
|
||||||
|
vBC = barycentric;
|
||||||
|
|
||||||
|
t = sLast - sCurrent;
|
||||||
|
n1 = vec2 (0.0);
|
||||||
|
if (dot (t, t) > 0.001)
|
||||||
|
n1 = normalize (t);
|
||||||
|
t = sCurrent - sNext;
|
||||||
|
n2 = vec2 (0.0);
|
||||||
|
if (dot (t, t) > 0.001)
|
||||||
|
n2 = normalize (t);
|
||||||
|
n = vec2 (0.0);
|
||||||
|
if (n1 != -n2)
|
||||||
|
n = normalize (n1 + n2);
|
||||||
|
else if (dot (n1, n1) > 0.001)
|
||||||
|
n = n1;
|
||||||
|
else if (dot (n2, n2) > 0.001)
|
||||||
|
n = n2;
|
||||||
|
|
||||||
|
// rotate the normal by 90 degrees and scale by the desired width
|
||||||
|
vec2 dir = vec2 (n.y, -n.x) * off;
|
||||||
|
float scale = estimateScale (current.xyz, sCurrent);
|
||||||
|
vec2 pos = sCurrent + dir * scale;
|
||||||
|
|
||||||
|
gl_Position = unproject (pos, dCurrent.z, dCurrent.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Fragment.particle.trail
|
||||||
|
|
||||||
|
uniform sampler2D smoke;
|
||||||
|
|
||||||
|
varying vec2 texcoord;
|
||||||
|
varying vec3 vBC;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
gl_FragColor = texture2D (smoke, texcoord) * vec4 (1.0, 1.0, 1.0, 0.7);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
float
|
||||||
|
edgeFactor (void)
|
||||||
|
{
|
||||||
|
vec3 d = fwidth (vBC);
|
||||||
|
vec3 a3 = smoothstep (vec3 (0.0), d * 1.5, vBC);
|
||||||
|
return min (min (a3.x, a3.y), a3.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4 (vec3 (edgeFactor ()), 0.5);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
uniform sampler2D smoke;
|
|
||||||
|
|
||||||
varying vec2 texcoord;
|
|
||||||
varying vec3 vBC;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
gl_FragColor = texture2D (smoke, texcoord) * vec4 (1.0, 1.0, 1.0, 0.7);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
float
|
|
||||||
edgeFactor (void)
|
|
||||||
{
|
|
||||||
vec3 d = fwidth (vBC);
|
|
||||||
vec3 a3 = smoothstep (vec3 (0.0), d * 1.5, vBC);
|
|
||||||
return min (min (a3.x, a3.y), a3.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
gl_FragColor = vec4 (vec3 (edgeFactor ()), 0.5);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,79 +0,0 @@
|
||||||
attribute vec4 last, current, next;
|
|
||||||
attribute vec3 barycentric;
|
|
||||||
attribute float texoff;
|
|
||||||
|
|
||||||
uniform mat4 proj, view;
|
|
||||||
uniform vec2 viewport;
|
|
||||||
uniform float width;
|
|
||||||
|
|
||||||
varying vec2 texcoord;
|
|
||||||
varying vec3 vBC;
|
|
||||||
|
|
||||||
vec4
|
|
||||||
transform (vec3 coord)
|
|
||||||
{
|
|
||||||
return proj * view * vec4 (coord, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2
|
|
||||||
project (vec4 coord)
|
|
||||||
{
|
|
||||||
vec3 device = coord.xyz / coord.w;
|
|
||||||
vec2 clip = (device * 0.5 + 0.5).xy;
|
|
||||||
return clip * viewport;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4
|
|
||||||
unproject (vec2 screen, float z, float w)
|
|
||||||
{
|
|
||||||
vec2 clip = screen / viewport;
|
|
||||||
vec2 device = clip * 2.0 - 1.0;
|
|
||||||
return vec4 (device * w, z, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
estimateScale (vec3 position, vec2 sPosition)
|
|
||||||
{
|
|
||||||
vec4 view_pos = view * vec4 (position, 1.0);
|
|
||||||
vec4 scale_pos = view_pos - vec4 (normalize (view_pos.xy) * width,
|
|
||||||
0.0, 0.0);
|
|
||||||
vec2 screen_scale_pos = project (proj * scale_pos);
|
|
||||||
return distance (sPosition, screen_scale_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
vec2 t, n1, n2, n;
|
|
||||||
vec2 sLast = project (transform (last.xyz));
|
|
||||||
vec2 sNext = project (transform (next.xyz));
|
|
||||||
vec4 dCurrent = transform (current.xyz);
|
|
||||||
vec2 sCurrent = project (dCurrent);
|
|
||||||
float off = current.w;
|
|
||||||
|
|
||||||
texcoord = vec2 (texoff * 0.7, off * 0.5 + 0.5);
|
|
||||||
vBC = barycentric;
|
|
||||||
|
|
||||||
t = sLast - sCurrent;
|
|
||||||
n1 = vec2 (0.0);
|
|
||||||
if (dot (t, t) > 0.001)
|
|
||||||
n1 = normalize (t);
|
|
||||||
t = sCurrent - sNext;
|
|
||||||
n2 = vec2 (0.0);
|
|
||||||
if (dot (t, t) > 0.001)
|
|
||||||
n2 = normalize (t);
|
|
||||||
n = vec2 (0.0);
|
|
||||||
if (n1 != -n2)
|
|
||||||
n = normalize (n1 + n2);
|
|
||||||
else if (dot (n1, n1) > 0.001)
|
|
||||||
n = n1;
|
|
||||||
else if (dot (n2, n2) > 0.001)
|
|
||||||
n = n2;
|
|
||||||
|
|
||||||
// rotate the normal by 90 degrees and scale by the desired width
|
|
||||||
vec2 dir = vec2 (n.y, -n.x) * off;
|
|
||||||
float scale = estimateScale (current.xyz, sCurrent);
|
|
||||||
vec2 pos = sCurrent + dir * scale;
|
|
||||||
|
|
||||||
gl_Position = unproject (pos, dCurrent.z, dCurrent.w);
|
|
||||||
}
|
|
Loading…
Reference in a new issue