mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +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_CPPFLAGS= -I$(top_srcdir)/include $(GLX_CFLAGS)
|
||||
|
||||
shader_src= quakeforge.glsl trail.frag trail.vert
|
||||
shader_gen= quakeforge.slc trail.fc trail.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 \
|
||||
|
|
|
@ -107,13 +107,17 @@ static const char *particle_textured_frag_effects[] =
|
|||
0
|
||||
};
|
||||
|
||||
static const char trail_vert[] =
|
||||
#include "trail.vc"
|
||||
;
|
||||
static const char *particle_trail_vert_effects[] =
|
||||
{
|
||||
"QuakeForge.Vertex.particle.trail",
|
||||
0
|
||||
};
|
||||
|
||||
static const char trail_frag[] =
|
||||
#include "trail.fc"
|
||||
;
|
||||
static const char *particle_trail_frag_effects[] =
|
||||
{
|
||||
"QuakeForge.Fragment.particle.trail",
|
||||
0
|
||||
};
|
||||
|
||||
static struct {
|
||||
int program;
|
||||
|
@ -190,9 +194,9 @@ typedef struct trailvtx_s {
|
|||
float texoff;
|
||||
} trailvtx_t;
|
||||
|
||||
static trail_t *free_trails;
|
||||
static trail_t *active_trails;
|
||||
static particle_t *free_points;
|
||||
static trail_t *trails_freelist;
|
||||
static trail_t *trails_active;
|
||||
static particle_t *points_freelist;
|
||||
|
||||
static trail_t *
|
||||
new_trail (void)
|
||||
|
@ -350,8 +354,10 @@ glsl_R_InitParticles (void)
|
|||
GLSL_FreeShader (vert_shader);
|
||||
GLSL_FreeShader (frag_shader);
|
||||
|
||||
vert = GLSL_CompileShader ("trail.vert", trail_vert, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("trail.frag", trail_frag, GL_FRAGMENT_SHADER);
|
||||
vert_shader = GLSL_BuildShader (particle_trail_vert_effects);
|
||||
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);
|
||||
GLSL_ResolveShaderParam (trail.program, &trail.proj);
|
||||
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.texoff);
|
||||
GLSL_ResolveShaderParam (trail.program, &trail.smoke);
|
||||
GLSL_FreeShader (vert_shader);
|
||||
GLSL_FreeShader (frag_shader);
|
||||
|
||||
memset (data, 0, sizeof (data));
|
||||
qfeglGenTextures (1, &part_tex);
|
||||
|
@ -730,12 +738,12 @@ R_RocketTrail_trail (entity_t *ent)
|
|||
|
||||
if (!ent->trail) {
|
||||
ent->trail = new_trail ();
|
||||
ent->trail->next = active_trails;
|
||||
ent->trail->prev = &active_trails;
|
||||
ent->trail->next = trails_active;
|
||||
ent->trail->prev = &trails_active;
|
||||
ent->trail->owner = &ent->trail;
|
||||
if (active_trails)
|
||||
active_trails->prev = &ent->trail->next;
|
||||
active_trails = ent->trail;
|
||||
if (trails_active)
|
||||
trails_active->prev = &ent->trail->next;
|
||||
trails_active = ent->trail;
|
||||
}
|
||||
|
||||
VectorCopy (ent->old_origin, old_origin);
|
||||
|
@ -1723,7 +1731,7 @@ count_points (int *num_verts, int *num_elements)
|
|||
|
||||
*num_verts = 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)
|
||||
continue;
|
||||
// +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};
|
||||
int bind = 0;
|
||||
|
||||
for (trail = active_trails; trail; trail = trail->next) {
|
||||
for (trail = trails_active; trail; trail = trail->next) {
|
||||
if (trail->num_points < 2)
|
||||
continue;
|
||||
point = trail->points;
|
||||
|
@ -1768,7 +1776,7 @@ expire_trails (void)
|
|||
{
|
||||
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;
|
||||
while (trail->points && trail->points->die <= vr_data.realtime) {
|
||||
particle_t *point = trail->points;
|
||||
|
@ -1827,7 +1835,7 @@ draw_trails (void)
|
|||
qfeglVertexAttribPointer (trail.texoff.location, 1, GL_FLOAT,
|
||||
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;
|
||||
if (trl->num_points < 2)
|
||||
continue;
|
||||
|
|
|
@ -551,3 +551,114 @@ main (void)
|
|||
col = texture2D (texture, st) * color * vec4 (l, 1.0);
|
||||
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