mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
Start working on solid trails for smoke etc.
The implementation is based on http://codeflow.org/entries/2012/aug/05/webgl-rendering-of-solid-trails/ The shaders have been written and compile and link. The next step is to generate some data for them.
This commit is contained in:
parent
946561ba44
commit
ddd8885cd6
4 changed files with 128 additions and 2 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
|
shader_src= quakeforge.glsl trail.frag trail.vert
|
||||||
shader_gen= quakeforge.slc
|
shader_gen= quakeforge.slc trail.fc trail.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 \
|
||||||
|
|
|
@ -106,6 +106,14 @@ static const char *particle_textured_frag_effects[] =
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char trail_vert[] =
|
||||||
|
#include "trail.vc"
|
||||||
|
;
|
||||||
|
|
||||||
|
static const char trail_frag[] =
|
||||||
|
#include "trail.fc"
|
||||||
|
;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int program;
|
int program;
|
||||||
shaderparam_t mvp_matrix;
|
shaderparam_t mvp_matrix;
|
||||||
|
@ -140,6 +148,32 @@ static struct {
|
||||||
{"fog", 1},
|
{"fog", 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int program;
|
||||||
|
shaderparam_t proj;
|
||||||
|
shaderparam_t view;
|
||||||
|
shaderparam_t viewport;
|
||||||
|
shaderparam_t width;
|
||||||
|
shaderparam_t last;
|
||||||
|
shaderparam_t current;
|
||||||
|
shaderparam_t next;
|
||||||
|
shaderparam_t barycentric;
|
||||||
|
shaderparam_t texoff;
|
||||||
|
shaderparam_t smoke;
|
||||||
|
} trail = {
|
||||||
|
0,
|
||||||
|
{"proj", 1},
|
||||||
|
{"view", 1},
|
||||||
|
{"viewport", 1},
|
||||||
|
{"width", 1},
|
||||||
|
{"last", 0},
|
||||||
|
{"current", 0},
|
||||||
|
{"next", 0},
|
||||||
|
{"barycentric", 0},
|
||||||
|
{"texoff", 0},
|
||||||
|
{"smoke", 1},
|
||||||
|
};
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
|
particle_new (ptype_t type, int texnum, const vec3_t org, float scale,
|
||||||
const vec3_t vel, float die, int color, float alpha, float ramp)
|
const vec3_t vel, float die, int color, float alpha, float ramp)
|
||||||
|
@ -267,6 +301,20 @@ 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);
|
||||||
|
frag = GLSL_CompileShader ("trail.frag", trail_frag, GL_FRAGMENT_SHADER);
|
||||||
|
trail.program = GLSL_LinkProgram ("trail", vert, frag);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.proj);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.view);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.viewport);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.width);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.last);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.current);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.next);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.barycentric);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.texoff);
|
||||||
|
GLSL_ResolveShaderParam (trail.program, &trail.smoke);
|
||||||
|
|
||||||
memset (data, 0, sizeof (data));
|
memset (data, 0, sizeof (data));
|
||||||
qfeglGenTextures (1, &part_tex);
|
qfeglGenTextures (1, &part_tex);
|
||||||
qfeglBindTexture (GL_TEXTURE_2D, part_tex);
|
qfeglBindTexture (GL_TEXTURE_2D, part_tex);
|
||||||
|
|
10
libs/video/renderer/glsl/trail.frag
Normal file
10
libs/video/renderer/glsl/trail.frag
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
uniform sampler2D smoke;
|
||||||
|
|
||||||
|
varying vec2 texcoord;
|
||||||
|
varying vec3 vBC;
|
||||||
|
|
||||||
|
void
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
gl_FragColor = texture2D (smoke, texcoord) * vec4 (1.0, 1.0, 1.0, 0.7);
|
||||||
|
}
|
68
libs/video/renderer/glsl/trail.vert
Normal file
68
libs/video/renderer/glsl/trail.vert
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
// FIXME either n1 or n2 could be zero
|
||||||
|
vec2 n1 = normalize (sLast - sCurrent);
|
||||||
|
vec2 n2 = normalize (sCurrent - sNext);
|
||||||
|
// FIXME if n1 == -n2, the vector will be zero
|
||||||
|
vec2 n = normalize (n1 + 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