mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
Merge branch 'wip-trails'
This commit is contained in:
commit
7a2a61d365
28 changed files with 1595 additions and 22 deletions
|
@ -44,4 +44,8 @@ void glsl_R_Particles_Init_Cvars (void);
|
|||
void glsl_R_InitParticles (void);
|
||||
void glsl_R_ShutdownParticles (void);
|
||||
|
||||
void glsl_R_InitTrails (void);
|
||||
void glsl_R_ShutdownTrails (void);
|
||||
void glsl_R_DrawTrails (struct psystem_s *psystem);
|
||||
|
||||
#endif//__QF_GLSL_qf_particles_h
|
||||
|
|
|
@ -39,6 +39,7 @@ struct plitem_s;
|
|||
struct cvar_s;
|
||||
struct scene_s;
|
||||
struct skin_s;
|
||||
struct particle_s;
|
||||
|
||||
struct mod_alias_ctx_s;
|
||||
struct mod_sprite_ctx_s;
|
||||
|
@ -117,6 +118,7 @@ typedef struct vid_render_funcs_s {
|
|||
void (*Draw_Glyph) (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
struct psystem_s *(*ParticleSystem) (void);
|
||||
struct psystem_s *(*TrailSystem) (void);
|
||||
void (*R_Init) (void);
|
||||
void (*R_ClearState) (void);
|
||||
void (*R_LoadSkys) (const char *);
|
||||
|
@ -126,6 +128,7 @@ typedef struct vid_render_funcs_s {
|
|||
void (*begin_frame) (void);
|
||||
void (*render_view) (void);
|
||||
void (*draw_particles) (struct psystem_s *psystem);
|
||||
void (*draw_trails) (struct psystem_s *psystem);
|
||||
void (*draw_transparent) (void);
|
||||
void (*post_process) (struct framebuffer_s *src);
|
||||
void (*set_2d) (int scaled);
|
||||
|
|
|
@ -41,10 +41,8 @@ typedef enum {
|
|||
part_tex_smoke,
|
||||
} ptextype_t;
|
||||
|
||||
typedef struct particle_s particle_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
struct particle_s {
|
||||
typedef struct particle_s {
|
||||
vec4f_t pos;
|
||||
vec4f_t vel;
|
||||
|
||||
|
@ -61,7 +59,24 @@ struct particle_s {
|
|||
float ramp;
|
||||
float scale;
|
||||
float live;
|
||||
};
|
||||
} particle_t;
|
||||
|
||||
static_assert (sizeof (particle_t) == 4 * sizeof(vec4f_t),
|
||||
"particle_t wrong size");
|
||||
|
||||
typedef struct trailpnt_s {
|
||||
vec4f_t pos;
|
||||
vec4f_t vel;
|
||||
vec3_t bary;
|
||||
float pathoffset;
|
||||
byte colora[4];
|
||||
byte colorb[4];
|
||||
uint32_t trailid;
|
||||
float live;
|
||||
} trailpnt_t;
|
||||
|
||||
static_assert (sizeof (trailpnt_t) == 4 * sizeof(vec4f_t),
|
||||
"trailprt_t wrong size");
|
||||
|
||||
typedef struct partparm_s {
|
||||
vec4f_t drag; // drag[3] is grav scale
|
||||
|
@ -71,6 +86,9 @@ typedef struct partparm_s {
|
|||
float alpha_rate;
|
||||
} partparm_t;
|
||||
|
||||
static_assert (sizeof (partparm_t) == 2 * sizeof(vec4f_t),
|
||||
"partparm_t wrong size");
|
||||
|
||||
typedef struct psystem_s {
|
||||
vec4f_t gravity;
|
||||
uint32_t maxparticles;
|
||||
|
@ -186,4 +204,9 @@ void Fog_StartAdditive (void);
|
|||
void Fog_StopAdditive (void);
|
||||
void Fog_Init (void);
|
||||
|
||||
bool R_Trail_Valid (psystem_t *system, uint32_t trailid) __attribute__((pure));
|
||||
uint32_t R_Trail_Create (psystem_t *system, int num_points, vec4f_t start);
|
||||
void R_Trail_Update (psystem_t *system, uint32_t trailid, vec4f_t pos);
|
||||
void R_Trail_Destroy (psystem_t *system, uint32_t trailid);
|
||||
|
||||
#endif//__QF_render_h
|
||||
|
|
|
@ -75,6 +75,7 @@ typedef struct visibility_s {
|
|||
typedef struct renderer_s {
|
||||
struct model_s *model; // NULL = no model
|
||||
struct skin_s *skin;
|
||||
struct trail_s *trail;
|
||||
unsigned fullbright:1;
|
||||
unsigned noshadows:1;
|
||||
unsigned onlyshadows:1;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
enum {
|
||||
effect_light, // light entity id
|
||||
effect_muzzleflash, // light entity id
|
||||
effect_trail, // trail id
|
||||
|
||||
effect_comp_count,
|
||||
};
|
||||
|
@ -54,5 +55,6 @@ void CL_EntityEffects (struct entity_s ent, struct entity_state_s *state,
|
|||
double time);
|
||||
void CL_MuzzleFlash (struct entity_s ent, vec4f_t position, vec4f_t fv,
|
||||
float zoffset, double time);
|
||||
void CL_Effects_Init (void);
|
||||
|
||||
#endif//__client_effects_h
|
||||
|
|
|
@ -56,6 +56,17 @@ typedef struct
|
|||
float zi;
|
||||
} emitpoint_t;
|
||||
|
||||
typedef struct particle_s particle_t;
|
||||
|
||||
void R_LoadParticles (void);
|
||||
bool R_CompileParticlePhysics (const char *name, const char *code);
|
||||
void R_RunParticlePhysics (particle_t *part);
|
||||
const union pt_phys_op_s *R_ParticlePhysics (const char *type);
|
||||
bool R_AddParticlePhysicsFunction (const char *name,
|
||||
bool (*func) (struct particle_s *, void *),
|
||||
void *data);
|
||||
extern const char particle_types[];
|
||||
|
||||
#define PARTICLE_Z_CLIP 8.0
|
||||
|
||||
typedef struct polyvert_s {
|
||||
|
|
|
@ -45,10 +45,13 @@ typedef enum {
|
|||
|
||||
struct entity_s;
|
||||
|
||||
void R_Particles_Init_Cvars (void);
|
||||
void R_InitBubble (void);
|
||||
void R_Trails_Init (void);
|
||||
void R_Trails_Init_Cvars (void);
|
||||
void R_ClearTrails (void);
|
||||
void R_RunTrails (float dT);
|
||||
|
||||
void R_InitParticles (void);
|
||||
void R_RunParticles (float dT);
|
||||
void R_Particles_Init_Cvars (void);
|
||||
void R_ClearParticles (void);
|
||||
void R_InitSprites (void);
|
||||
|
||||
|
|
|
@ -42,10 +42,11 @@ void R_ViewChanged (void); // must set r_refdef first
|
|||
// called whenever r_refdef or vid change
|
||||
|
||||
extern struct psystem_s r_psystem;
|
||||
extern struct psystem_s r_tsystem;
|
||||
struct psystem_s *gl_ParticleSystem (void);
|
||||
struct psystem_s *glsl_ParticleSystem (void);
|
||||
struct psystem_s *glsl_TrailSystem (void);
|
||||
struct psystem_s *sw_ParticleSystem (void);
|
||||
void R_RunParticles (float dT);
|
||||
|
||||
struct scene_s;
|
||||
void R_NewScene (struct scene_s *scene);
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
noinst_LTLIBRARIES += libs/client/libQFclient.la
|
||||
|
||||
particles_src= libs/client/particles.part
|
||||
particles_gen= libs/client/particles.pc
|
||||
|
||||
SUFFICES += .part .pc
|
||||
.part.pc:
|
||||
$(V_SED)sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' $< > $@.t &&\
|
||||
$(am__mv) $@.t $@
|
||||
|
||||
libs_client_libQFclient_la_LDFLAGS= @STATIC@
|
||||
libs_client_libQFclient_la_LIBADD= \
|
||||
libs/ui/libQFgui.la \
|
||||
|
@ -24,9 +32,13 @@ libs_client_libQFclient_la_SOURCES= \
|
|||
default_input_src = libs/client/default_input.plist
|
||||
default_input_gen = libs/client/default_input.plc
|
||||
|
||||
libs/client/cl_input.lo: libs/client/cl_input.c $(default_input_gen)
|
||||
|
||||
EXTRA_DIST += \
|
||||
libs/client/default_input.plist
|
||||
$(default_input_src) \
|
||||
$(particles_src)
|
||||
CLEANFILES += \
|
||||
libs/client/*.plc
|
||||
libs/client/*.plc \
|
||||
libs/client/*.pc
|
||||
|
||||
BUILT_SOURCES += \
|
||||
$(default_input_gen) \
|
||||
$(particles_gen)
|
||||
|
|
|
@ -53,6 +53,15 @@
|
|||
|
||||
ecs_system_t effect_system;
|
||||
|
||||
static psystem_t *cl_tsystem;
|
||||
|
||||
static void
|
||||
cl_destroy_trail (void *comp)
|
||||
{
|
||||
auto trail = *(uint32_t *) comp;
|
||||
R_Trail_Destroy (cl_tsystem, trail);
|
||||
}
|
||||
|
||||
const component_t effect_components[effect_comp_count] = {
|
||||
[effect_light] = {
|
||||
.size = sizeof (uint32_t),
|
||||
|
@ -62,9 +71,15 @@ const component_t effect_components[effect_comp_count] = {
|
|||
.size = sizeof (uint32_t),
|
||||
.name = "muzzle flash",
|
||||
},
|
||||
[effect_trail] = {
|
||||
.size = sizeof (uint32_t),
|
||||
.name = "effect trail",
|
||||
.destroy = cl_destroy_trail,
|
||||
},
|
||||
};
|
||||
|
||||
#define c_light (effect_system.base + effect_light)
|
||||
#define c_trail (effect_system.base + effect_trail)
|
||||
|
||||
static bool
|
||||
has_light (entity_t ent)
|
||||
|
@ -98,6 +113,27 @@ attach_light_ent (entity_t ent)
|
|||
return light;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_trail (entity_t ent)
|
||||
{
|
||||
return Ent_HasComponent (ent.id, c_trail, ent.reg);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_trail (entity_t ent)
|
||||
{
|
||||
if (!has_trail (ent)) {
|
||||
return nullent;
|
||||
}
|
||||
return *(uint32_t *) Ent_GetComponent (ent.id, c_trail, ent.reg);
|
||||
}
|
||||
|
||||
static void
|
||||
set_trail (entity_t ent, uint32_t trail)
|
||||
{
|
||||
Ent_SetComponent (ent.id, c_trail, ent.reg, &trail);
|
||||
}
|
||||
|
||||
void
|
||||
CL_NewDlight (entity_t ent, vec4f_t org, int effects, byte glow_size,
|
||||
byte glow_color, double time)
|
||||
|
@ -181,6 +217,14 @@ CL_ModelEffects (entity_t ent, int glow_color, double time)
|
|||
});
|
||||
Light_LinkLight (cl_world.scene->lights, light);
|
||||
clp_funcs->RocketTrail (*old_origin, ent_origin);
|
||||
if (cl_tsystem) {
|
||||
uint32_t trail = get_trail (ent);
|
||||
if (R_Trail_Valid (cl_tsystem, trail)) {
|
||||
R_Trail_Update (cl_tsystem, trail, ent_origin);
|
||||
} else {
|
||||
set_trail (ent, R_Trail_Create (cl_tsystem, 30, ent_origin));
|
||||
}
|
||||
}
|
||||
renderer->noshadows = 1;
|
||||
} else if (model->effects & ME_GRENADE)
|
||||
clp_funcs->GrenadeTrail (*old_origin, ent_origin);
|
||||
|
@ -210,3 +254,11 @@ CL_EntityEffects (entity_t ent, entity_state_t *state, double time)
|
|||
CL_MuzzleFlash (ent, position, fv, 16, time);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CL_Effects_Init (void)
|
||||
{
|
||||
if (r_funcs->TrailSystem) {
|
||||
cl_tsystem = r_funcs->TrailSystem ();
|
||||
}
|
||||
}
|
||||
|
|
87
libs/client/particles.part
Normal file
87
libs/client/particles.part
Normal file
|
@ -0,0 +1,87 @@
|
|||
All of QuakeForge's standard particle physics functions converted to a script
|
||||
-- pt_static
|
||||
add_vel
|
||||
|
||||
-- pt_grav
|
||||
add_vel
|
||||
add_grav
|
||||
|
||||
-- pt_slowgrav
|
||||
add_vel
|
||||
add_grav
|
||||
|
||||
-- pt_fire
|
||||
add_ramp 5 6
|
||||
add_vel
|
||||
color_ramp3
|
||||
alpha_ramp 6
|
||||
sub_grav
|
||||
|
||||
-- pt_float
|
||||
add_vel
|
||||
sub_grav
|
||||
|
||||
-- pt_explode
|
||||
add_ramp 10 8
|
||||
add_vel
|
||||
color_ramp1
|
||||
explode_vel 4
|
||||
add_grav
|
||||
|
||||
-- pt_explode2
|
||||
add_ramp 15 8
|
||||
add_vel
|
||||
color_ramp2
|
||||
explode_vel 1
|
||||
add_grav
|
||||
|
||||
-- pt_blob
|
||||
add_vel
|
||||
explode_vel 4
|
||||
add_grav
|
||||
|
||||
-- pt_blob2
|
||||
add_vel
|
||||
damp_vel 4
|
||||
add_grav
|
||||
|
||||
-- pt_smoke
|
||||
fade_alpha 0.4
|
||||
add_vel
|
||||
grow_scale 4
|
||||
//sub_slowgrav
|
||||
|
||||
-- pt_smokecloud
|
||||
fade_alpha 0.55
|
||||
add_vel
|
||||
grow_scale 50
|
||||
sub_slowgrav
|
||||
|
||||
-- pt_bloodcloud
|
||||
fade_alpha 0.25
|
||||
add_vel
|
||||
grow_scale 4
|
||||
add_grav
|
||||
|
||||
-- pt_fadespark
|
||||
add_vel
|
||||
|
||||
-- pt_fadespark2
|
||||
add_vel
|
||||
|
||||
-- pt_fallfade
|
||||
fade_alpha 1
|
||||
add_vel
|
||||
add_fastgrav
|
||||
|
||||
-- pt_fallfadespark
|
||||
add_ramp 15 8
|
||||
fade_alpha 1
|
||||
color_ramp1
|
||||
add_vel
|
||||
add_fastgrav
|
||||
|
||||
-- pt_flame
|
||||
fade_alpha 0.125
|
||||
add_vel
|
||||
shrink_scale 2
|
|
@ -151,10 +151,9 @@ Segtext_new (const char *source_string)
|
|||
(*chunk)->text = src;
|
||||
(*chunk)->start_line = line;
|
||||
|
||||
chunk = &(*chunk)->next;
|
||||
|
||||
while ((src = next_chunk (src, &line))) {
|
||||
*src++ = 0; // terminate the previous chunk
|
||||
chunk = &(*chunk)->next;
|
||||
*chunk = new_chunk ();
|
||||
(*chunk)->tag = find_tag (src);
|
||||
src = next_line (src, &line);
|
||||
|
@ -163,7 +162,6 @@ Segtext_new (const char *source_string)
|
|||
// If tags are duplicated, the first one takes precedence
|
||||
if ((*chunk)->tag && !Hash_Find (text->tab, (*chunk)->tag))
|
||||
Hash_Add (text->tab, *chunk);
|
||||
chunk = &(*chunk)->next;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -58,9 +58,10 @@ libs_video_renderer_libQFrenderer_la_SOURCES=\
|
|||
libs/video/renderer/r_light.c \
|
||||
libs/video/renderer/r_main.c \
|
||||
libs/video/renderer/r_part.c \
|
||||
libs/video/renderer/r_progs.c \
|
||||
libs/video/renderer/r_scrap.c \
|
||||
libs/video/renderer/r_screen.c \
|
||||
libs/video/renderer/r_progs.c
|
||||
libs/video/renderer/r_trails.c
|
||||
|
||||
video_renderer_gl_libs= \
|
||||
libs/video/renderer/librender_gl.la \
|
||||
|
@ -97,12 +98,18 @@ libs_video_renderer_librender_gl_la_SOURCES = \
|
|||
libs/video/renderer/gl/vid_common_gl.c \
|
||||
libs/video/renderer/gl/vtxarray.c
|
||||
|
||||
shader_src= libs/video/renderer/glsl/quakeforge.glsl
|
||||
shader_gen= libs/video/renderer/glsl/quakeforge.slc
|
||||
glslshaderpath = libs/video/renderer/glsl
|
||||
|
||||
shader_src = \
|
||||
$(glslshaderpath)/quakeforge.glsl \
|
||||
$(glslshaderpath)/sgustavson.glsl
|
||||
shader_gen = \
|
||||
$(glslshaderpath)/quakeforge.slc \
|
||||
$(glslshaderpath)/sgustavson.slc
|
||||
|
||||
SUFFIXES += .frag .vert .spv .spvc .fc .vc .slc .glsl
|
||||
.glsl.slc:
|
||||
$(V_SED)sed -e 's/^/"/' -e 's/$$/\\n"/' $< > $@.t &&\
|
||||
$(V_SED)sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' $< > $@.t &&\
|
||||
$(am__mv) $@.t $@
|
||||
|
||||
video_renderer_glsl_libs= \
|
||||
|
@ -129,6 +136,7 @@ libs_video_renderer_librender_glsl_la_SOURCES = \
|
|||
libs/video/renderer/glsl/glsl_shader.c \
|
||||
libs/video/renderer/glsl/glsl_sprite.c \
|
||||
libs/video/renderer/glsl/glsl_textures.c \
|
||||
libs/video/renderer/glsl/glsl_trails.c \
|
||||
libs/video/renderer/glsl/glsl_warp.c \
|
||||
libs/video/renderer/glsl/qfglsl.c \
|
||||
libs/video/renderer/glsl/quakeforge.glsl \
|
||||
|
|
|
@ -186,6 +186,7 @@ glsl_R_Init (void)
|
|||
glsl_R_InitIQM ();
|
||||
glsl_R_InitSprites ();
|
||||
glsl_R_InitParticles ();
|
||||
glsl_R_InitTrails ();
|
||||
glsl_InitFisheye ();
|
||||
glsl_InitWarp ();
|
||||
Skin_Init ();
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/image.h"
|
||||
|
@ -178,7 +179,9 @@ glsl_R_InitParticles (void)
|
|||
float v[2] = {0, 0};
|
||||
byte data[64][64][2];
|
||||
tex_t *tex;
|
||||
|
||||
#if 0
|
||||
R_LoadParticles ();
|
||||
#endif
|
||||
Cvar_AddListener (Cvar_FindVar ("r_particles"), glsl_particles_f, 0);
|
||||
Cvar_AddListener (Cvar_FindVar ("r_particles_max"), glsl_particles_f, 0);
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ GLSL_BuildShader (const char **effect_keys)
|
|||
chunk->start_line + 1,
|
||||
chunk->text + vline_len);
|
||||
} else {
|
||||
shader->strings[num] = nva ("#line %d\n%s", chunk->start_line,
|
||||
shader->strings[num] = nva ("#line %d\n%s", chunk->start_line - 1,
|
||||
chunk->text);
|
||||
}
|
||||
shader->src[num] = strdup (ekey->str);
|
||||
|
|
333
libs/video/renderer/glsl/glsl_trails.c
Normal file
333
libs/video/renderer/glsl/glsl_trails.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
glsl_trails.c
|
||||
|
||||
OpenGL trail system.
|
||||
|
||||
Copyright (C) 2013 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/image.h"
|
||||
#include "QF/mersenne.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "QF/GLSL/defines.h"
|
||||
#include "QF/GLSL/funcs.h"
|
||||
#include "QF/GLSL/qf_particles.h"
|
||||
#include "QF/GLSL/qf_textures.h"
|
||||
#include "QF/GLSL/qf_vid.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "r_local.h"
|
||||
|
||||
static uint32_t maxparticles;
|
||||
static GLushort *pVAindices;
|
||||
static partvert_t *particleVertexArray;
|
||||
|
||||
static const char *particle_trail_vert_effects[] =
|
||||
{
|
||||
"QuakeForge.Screen.viewport",
|
||||
"QuakeForge.Vertex.transform.view_projection",
|
||||
"QuakeForge.Vertex.ScreenSpace.curve.width",
|
||||
"QuakeForge.Vertex.particle.trail",
|
||||
0
|
||||
};
|
||||
|
||||
static const char *particle_trail_frag_effects[] =
|
||||
{
|
||||
"QuakeForge.Math.InvSqrt",
|
||||
"QuakeForge.Math.permute",
|
||||
"QuakeForge.Noise.simplex",
|
||||
"QuakeForge.Fragment.particle.trail",
|
||||
0
|
||||
};
|
||||
|
||||
static const char *particle_trail_debug_frag_effects[] =
|
||||
{
|
||||
"QuakeForge.Fragment.barycentric",
|
||||
0
|
||||
};
|
||||
|
||||
typedef 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 colora;
|
||||
shaderparam_t colorb;
|
||||
} trailprog_t;
|
||||
|
||||
static trailprog_t trail = {
|
||||
0,
|
||||
{"projection_mat", 1},
|
||||
{"view_mat", 1},
|
||||
{"viewport", 1},
|
||||
{"width", 1},
|
||||
{"last", 0},
|
||||
{"current", 0},
|
||||
{"next", 0},
|
||||
{"barycentric", 0},
|
||||
{"texoff", 0},
|
||||
{"vcolora", 0},
|
||||
{"vcolorb", 0},
|
||||
};
|
||||
static trailprog_t trail_debug;
|
||||
|
||||
typedef struct trailvtx_s {
|
||||
vec4f_t vertex;
|
||||
vec3_t bary;
|
||||
float texoff;
|
||||
byte colora[4];
|
||||
byte colorb[4];
|
||||
} trailvtx_t;
|
||||
|
||||
static void
|
||||
alloc_arrays (psystem_t *ps)
|
||||
{
|
||||
if (ps->maxparticles > maxparticles) {
|
||||
maxparticles = ps->maxparticles;
|
||||
if (particleVertexArray)
|
||||
free (particleVertexArray);
|
||||
printf ("alloc_arrays: %d\n", ps->maxparticles);
|
||||
particleVertexArray = calloc (ps->maxparticles * 4,
|
||||
sizeof (partvert_t));
|
||||
|
||||
if (pVAindices)
|
||||
free (pVAindices);
|
||||
pVAindices = calloc (ps->maxparticles * 6, sizeof (GLushort));
|
||||
for (uint32_t i = 0; i < ps->maxparticles; i++) {
|
||||
pVAindices[i * 6 + 0] = i * 4 + 0;
|
||||
pVAindices[i * 6 + 1] = i * 4 + 1;
|
||||
pVAindices[i * 6 + 2] = i * 4 + 2;
|
||||
pVAindices[i * 6 + 3] = i * 4 + 0;
|
||||
pVAindices[i * 6 + 4] = i * 4 + 2;
|
||||
pVAindices[i * 6 + 5] = i * 4 + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glsl_R_ShutdownTrails (void)
|
||||
{
|
||||
free (particleVertexArray);
|
||||
free (pVAindices);
|
||||
}
|
||||
|
||||
static void
|
||||
build_program (trailprog_t *prog, const char *name, int vert, int frag)
|
||||
{
|
||||
prog->program = GLSL_LinkProgram (name, vert, frag);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->proj);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->view);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->viewport);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->width);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->last);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->current);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->next);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->barycentric);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->texoff);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->colora);
|
||||
GLSL_ResolveShaderParam (prog->program, &prog->colorb);
|
||||
}
|
||||
|
||||
void
|
||||
glsl_R_InitTrails (void)
|
||||
{
|
||||
shader_t *vert_shader, *frag_shader, *debug_shader;
|
||||
int vert;
|
||||
int frag;
|
||||
int debug;
|
||||
|
||||
|
||||
vert_shader = GLSL_BuildShader (particle_trail_vert_effects);
|
||||
frag_shader = GLSL_BuildShader (particle_trail_frag_effects);
|
||||
debug_shader = GLSL_BuildShader (particle_trail_debug_frag_effects);
|
||||
vert = GLSL_CompileShader ("trail.vert", vert_shader, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("trail.frag", frag_shader, GL_FRAGMENT_SHADER);
|
||||
debug = GLSL_CompileShader ("trail.frag.debug", debug_shader,
|
||||
GL_FRAGMENT_SHADER);
|
||||
trail_debug = trail;
|
||||
build_program (&trail, "trail", vert, frag);
|
||||
build_program (&trail_debug, "trail.debug", vert, debug);
|
||||
|
||||
GLSL_FreeShader (vert_shader);
|
||||
GLSL_FreeShader (frag_shader);
|
||||
GLSL_FreeShader (debug_shader);
|
||||
|
||||
alloc_arrays (&r_psystem);
|
||||
}
|
||||
|
||||
static int
|
||||
count_bits (uint32_t v)
|
||||
{
|
||||
int c = 0;
|
||||
for (; v; c++) {
|
||||
v &= v - 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
count_points (uint32_t block_mask)
|
||||
{
|
||||
int num_blocks = count_bits (block_mask);
|
||||
return num_blocks * 64;
|
||||
}
|
||||
|
||||
static void
|
||||
build_verts (trailvtx_t *verts, int *counts,
|
||||
const trailpnt_t *points, uint32_t block_mask)
|
||||
{
|
||||
uint32_t id = ~0u;
|
||||
for (int m = 0; m < 32; m++, points += 64) {
|
||||
if (!(block_mask & (1 << m))) {
|
||||
if (*counts) {
|
||||
counts++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (id != ~0u && points->trailid != id) {
|
||||
counts++;
|
||||
}
|
||||
id = points->trailid;
|
||||
*counts += 64;
|
||||
for (int i = 0; i < 64; i++) {
|
||||
verts[i] = (trailvtx_t) {
|
||||
.vertex = points[i].pos,
|
||||
.bary = {VectorExpand (points[i].bary)},
|
||||
.texoff = points[i].pathoffset,
|
||||
.colora = { QuatExpand (points[i].colora)},
|
||||
.colorb = { QuatExpand (points[i].colorb)},
|
||||
};
|
||||
}
|
||||
verts += 64;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_trails (trailpnt_t *points, uint32_t block_mask)
|
||||
{
|
||||
int num_verts = count_points (block_mask);
|
||||
if (!num_verts) {
|
||||
return;
|
||||
}
|
||||
|
||||
trailvtx_t verts[num_verts];
|
||||
int counts[33] = {};
|
||||
build_verts (verts, counts, points, block_mask);
|
||||
|
||||
auto prog = trail;
|
||||
qfeglUseProgram (prog.program);
|
||||
qfeglEnableVertexAttribArray (prog.last.location);
|
||||
qfeglEnableVertexAttribArray (prog.current.location);
|
||||
qfeglEnableVertexAttribArray (prog.next.location);
|
||||
if (prog.barycentric.location >= 0)
|
||||
qfeglEnableVertexAttribArray (prog.barycentric.location);
|
||||
qfeglEnableVertexAttribArray (prog.texoff.location);
|
||||
if (prog.colora.location >= 0)
|
||||
qfeglEnableVertexAttribArray (prog.colora.location);
|
||||
if (prog.colorb.location >= 0)
|
||||
qfeglEnableVertexAttribArray (prog.colorb.location);
|
||||
|
||||
qfeglUniformMatrix4fv (prog.proj.location, 1, false,
|
||||
(vec_t*)&glsl_projection[0]);//FIXME
|
||||
qfeglUniformMatrix4fv (prog.view.location, 1, false,
|
||||
(vec_t*)&glsl_view[0]);//FIXME
|
||||
qfeglUniform2f (prog.viewport.location, r_refdef.vrect.width,
|
||||
r_refdef.vrect.height);
|
||||
qfeglUniform1f (prog.width.location, 10);
|
||||
|
||||
qfeglVertexAttribPointer (prog.last.location, 4, GL_FLOAT,
|
||||
0, sizeof (trailvtx_t), &verts[0].vertex);
|
||||
qfeglVertexAttribPointer (prog.current.location, 4, GL_FLOAT,
|
||||
0, sizeof (trailvtx_t), &verts[2].vertex);
|
||||
qfeglVertexAttribPointer (prog.next.location, 4, GL_FLOAT,
|
||||
0, sizeof (trailvtx_t), &verts[4].vertex);
|
||||
if (prog.barycentric.location >= 0)
|
||||
qfeglVertexAttribPointer (prog.barycentric.location, 3, GL_FLOAT,
|
||||
0, sizeof (trailvtx_t), &verts[2].bary);
|
||||
qfeglVertexAttribPointer (prog.texoff.location, 1, GL_FLOAT,
|
||||
0, sizeof (trailvtx_t), &verts[0].texoff);
|
||||
if (prog.colora.location >= 0)
|
||||
qfeglVertexAttribPointer (prog.colora.location, 4, GL_UNSIGNED_BYTE,
|
||||
1, sizeof (trailvtx_t), &verts[0].colora);
|
||||
if (prog.colorb.location >= 0)
|
||||
qfeglVertexAttribPointer (prog.colorb.location, 4, GL_UNSIGNED_BYTE,
|
||||
1, sizeof (trailvtx_t), &verts[0].colorb);
|
||||
|
||||
int first = 0;
|
||||
for (auto c = counts; *c; c++) {
|
||||
qfeglDrawArrays (GL_TRIANGLE_STRIP, first, *c - 4);
|
||||
first += *c;
|
||||
}
|
||||
|
||||
qfeglDisableVertexAttribArray (prog.last.location);
|
||||
qfeglDisableVertexAttribArray (prog.current.location);
|
||||
qfeglDisableVertexAttribArray (prog.next.location);
|
||||
if (prog.barycentric.location >= 0)
|
||||
qfeglDisableVertexAttribArray (prog.barycentric.location);
|
||||
qfeglDisableVertexAttribArray (prog.texoff.location);
|
||||
if (prog.colora.location >= 0)
|
||||
qfeglDisableVertexAttribArray (prog.colora.location);
|
||||
if (prog.colorb.location >= 0)
|
||||
qfeglDisableVertexAttribArray (prog.colorb.location);
|
||||
}
|
||||
|
||||
void
|
||||
glsl_R_DrawTrails (psystem_t *psystem)
|
||||
{
|
||||
//FIXME abuse of psystem_t
|
||||
draw_trails ((trailpnt_t *)psystem->particles, psystem->numparticles);
|
||||
}
|
||||
|
||||
psystem_t * __attribute__((const))//FIXME
|
||||
glsl_TrailSystem (void)
|
||||
{
|
||||
return &r_tsystem;
|
||||
}
|
|
@ -1,3 +1,30 @@
|
|||
quakeforge.glsl
|
||||
|
||||
Builtin QuakeForge GLSL shaders.
|
||||
|
||||
Copyright (C) 2013 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2013/05/12
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
-- Math.const
|
||||
|
||||
const float PI = 3.14159265;
|
||||
|
@ -23,6 +50,100 @@ dqtrans (vec4 q0, vec4 qe)
|
|||
return 2.0 * (Ts * qv + qs * Tv + cross (Tv, qv));
|
||||
}
|
||||
|
||||
-- Vertex.transform.mvp
|
||||
uniform mat4 mvp_mat;
|
||||
|
||||
-- Vertex.transform.view_projection
|
||||
uniform mat4 projection_mat, view_mat;
|
||||
|
||||
-- Screen.viewport
|
||||
uniform vec2 viewport;
|
||||
|
||||
-- Vertex.ScreenSpace.curve.width
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
vec2
|
||||
direction (vec2 from, vec2 to)
|
||||
{
|
||||
vec2 t = to - from;
|
||||
vec2 d = vec2 (0.0, 0.0);
|
||||
|
||||
if (dot (t, t) > 0.001) {
|
||||
d = normalize (t);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
vec2
|
||||
shared_direction (vec2 a, vec2 b)
|
||||
{
|
||||
vec2 d = a + b;
|
||||
|
||||
if (dot (d, d) > 0.001) {
|
||||
d = normalize (d);
|
||||
} else if (dot (a, a) > 0.001) {
|
||||
d = normalize (a);
|
||||
} else if (dot (b, b) > 0.001) {
|
||||
d = normalize (b);
|
||||
} else {
|
||||
d = vec2 (0.0);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
float
|
||||
estimateScale (vec3 position, vec2 sPosition, float width)
|
||||
{
|
||||
vec4 view_pos = view_mat * vec4 (position, 1.0);
|
||||
vec4 scale_pos = view_pos - vec4 (normalize (view_pos.xy) * width,
|
||||
0.0, 0.0);
|
||||
vec2 screen_scale_pos = project (projection_mat * scale_pos);
|
||||
return distance (sPosition, screen_scale_pos);
|
||||
}
|
||||
|
||||
vec4
|
||||
transform (vec4 coord)
|
||||
{
|
||||
return projection_mat * view_mat * vec4 (coord.xyz, 1.0);
|
||||
}
|
||||
|
||||
vec4
|
||||
curve_offset_vertex (vec4 last, vec4 current, vec4 next, float width)
|
||||
{
|
||||
float offset = current.w;
|
||||
|
||||
vec2 sLast = project (transform (last));
|
||||
vec2 sNext = project (transform (next));
|
||||
vec4 dCurrent = transform (current);
|
||||
vec2 sCurrent = project (dCurrent);
|
||||
|
||||
vec2 n1 = direction (sCurrent, sLast);
|
||||
vec2 n2 = direction (sNext, sCurrent);
|
||||
vec2 n = shared_direction (n1, n2);
|
||||
|
||||
// rotate the normal by 90 degrees and scale by the desired offset
|
||||
vec2 dir = vec2(n.y, -n.x) * offset;
|
||||
float scale = estimateScale (vec3(current), sCurrent, width);
|
||||
vec2 pos = sCurrent + dir * scale;
|
||||
|
||||
return unproject (pos, dCurrent.z, dCurrent.w);
|
||||
}
|
||||
|
||||
-- Fragment.fog
|
||||
|
||||
uniform vec4 fog;
|
||||
|
@ -569,6 +690,72 @@ main (void)
|
|||
gl_FragColor = fogBlend (col);
|
||||
}
|
||||
|
||||
-- Vertex.particle.trail
|
||||
|
||||
attribute vec4 last, current, next;
|
||||
attribute vec3 barycentric;
|
||||
attribute float texoff;
|
||||
attribute vec4 vcolora;
|
||||
attribute vec4 vcolorb;
|
||||
|
||||
uniform float width;
|
||||
|
||||
varying vec2 texcoord;
|
||||
varying vec3 vbarycentric;
|
||||
varying vec4 colora;
|
||||
varying vec4 colorb;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
colora = vcolora;
|
||||
colorb = vcolorb;
|
||||
texcoord = vec2 (texoff * 0.7, current.w);// * 0.5 + 0.5);
|
||||
vbarycentric = barycentric;
|
||||
|
||||
gl_Position = curve_offset_vertex (last, current, next, width);
|
||||
}
|
||||
|
||||
-- Fragment.particle.trail
|
||||
|
||||
varying vec2 texcoord;
|
||||
varying vec4 colora;
|
||||
varying vec4 colorb;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec3 tex3 = vec3 (texcoord, 0.5);
|
||||
float n = abs(snoise(tex3));
|
||||
n += 0.5 * abs(snoise(tex3 * 2.0));
|
||||
n += 0.25 * abs(snoise(tex3 * 4.0));
|
||||
n += 0.125 * abs(snoise(tex3 * 8.0));
|
||||
vec4 c = mix (colora, colorb, n);
|
||||
c.a *= exp (-4.0 * abs(texcoord.y));
|
||||
gl_FragColor = c;
|
||||
}
|
||||
|
||||
-- Fragment.barycentric
|
||||
|
||||
varying vec3 vbarycentric;
|
||||
varying vec2 texcoord;
|
||||
|
||||
float
|
||||
edgeFactor (void)
|
||||
{
|
||||
vec3 d = fwidth (vbarycentric);
|
||||
vec3 a3 = smoothstep (vec3 (0.0), d * 1.5, vbarycentric);
|
||||
return min (min (a3.x, a3.y), a3.z);
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
//gl_FragColor = vec4 (vec3 (edgeFactor ()), 0.5);
|
||||
vec4 c = vec4 (vec3 (edgeFactor ()), 0.5);
|
||||
c.a *= 1.0 - exp (-4.0 * (1.0 - texcoord.y * texcoord.y));
|
||||
gl_FragColor = c;
|
||||
}
|
||||
-- version.130
|
||||
#version 130
|
||||
-- Vertex.fstri
|
||||
|
|
592
libs/video/renderer/glsl/sgustavson.glsl
Normal file
592
libs/video/renderer/glsl/sgustavson.glsl
Normal file
|
@ -0,0 +1,592 @@
|
|||
Note that the GPL covers only the arrangement in this file. The actual code
|
||||
is covered by the MIT licence (see LICENCE.txt below).
|
||||
|
||||
This file is just all the shader code presented by Stefan Gustavson
|
||||
collected into one file and split into useable sections with redundant
|
||||
code removed.
|
||||
|
||||
--
|
||||
|
||||
sgustavson.glsl
|
||||
|
||||
GLSL noise functions
|
||||
|
||||
Copyright (C) 2014 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2014/01/29
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
-- LICENCE.txt
|
||||
|
||||
Copyright (C) 2011 by Stefan Gustavson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
-- Math.permute
|
||||
|
||||
vec4 permute(vec4 x)
|
||||
{
|
||||
return mod(((x*34.0)+1.0)*x, 289.0);
|
||||
}
|
||||
|
||||
-- Math.InvSqrt
|
||||
|
||||
vec4 taylorInvSqrt(vec4 r)
|
||||
{
|
||||
return 1.79284291400159 - 0.85373472095314 * r;
|
||||
}
|
||||
|
||||
-- Noise.simplex
|
||||
|
||||
// Description : Array and textureless GLSL 3D simplex noise function.
|
||||
// Author : Ian McEwan, Ashima Arts.
|
||||
// Maintainer : ijm
|
||||
// Lastmod : 20110409 (stegu)
|
||||
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
||||
// Distributed under the MIT License. See LICENSE file.
|
||||
|
||||
float snoise(vec3 v)
|
||||
{
|
||||
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
|
||||
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
||||
|
||||
// First corner
|
||||
vec3 i = floor(v + dot(v, C.yyy) );
|
||||
vec3 x0 = v - i + dot(i, C.xxx) ;
|
||||
|
||||
// Other corners
|
||||
vec3 g = step(x0.yzx, x0.xyz);
|
||||
vec3 l = 1.0 - g;
|
||||
vec3 i1 = min( g.xyz, l.zxy );
|
||||
vec3 i2 = max( g.xyz, l.zxy );
|
||||
|
||||
// x0 = x0 - 0. + 0.0 * C
|
||||
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
|
||||
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
|
||||
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
|
||||
|
||||
// Permutations
|
||||
i = mod(i, 289.0 );
|
||||
vec4 p = permute( permute( permute(
|
||||
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
|
||||
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
|
||||
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
|
||||
|
||||
// Gradients
|
||||
// ( N*N points uniformly over a square, mapped onto an octahedron.)
|
||||
float n_ = 1.0/7.0; // N=7
|
||||
vec3 ns = n_ * D.wyz - D.xzx;
|
||||
|
||||
vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
|
||||
|
||||
vec4 x_ = floor(j * ns.z);
|
||||
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
|
||||
|
||||
vec4 x = x_ *ns.x + ns.yyyy;
|
||||
vec4 y = y_ *ns.x + ns.yyyy;
|
||||
vec4 h = 1.0 - abs(x) - abs(y);
|
||||
|
||||
vec4 b0 = vec4( x.xy, y.xy );
|
||||
vec4 b1 = vec4( x.zw, y.zw );
|
||||
|
||||
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
||||
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
||||
vec4 s0 = floor(b0)*2.0 + 1.0;
|
||||
vec4 s1 = floor(b1)*2.0 + 1.0;
|
||||
vec4 sh = -step(h, vec4(0.0));
|
||||
|
||||
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
|
||||
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
|
||||
|
||||
vec3 p0 = vec3(a0.xy,h.x);
|
||||
vec3 p1 = vec3(a0.zw,h.y);
|
||||
vec3 p2 = vec3(a1.xy,h.z);
|
||||
vec3 p3 = vec3(a1.zw,h.w);
|
||||
|
||||
//Normalise gradients
|
||||
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
|
||||
p0 *= norm.x;
|
||||
p1 *= norm.y;
|
||||
p2 *= norm.z;
|
||||
p3 *= norm.w;
|
||||
|
||||
// Mix final noise value
|
||||
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
||||
m = m * m;
|
||||
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
|
||||
dot(p2,x2), dot(p3,x3) ) );
|
||||
}
|
||||
|
||||
-- Vertex.simplex
|
||||
|
||||
uniform float time;
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vTexCoord3D = gl_Vertex.xyz * 4.0 + vec3(0.0, 0.0, time);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
-- Fragment.simplex
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
void main( void )
|
||||
{
|
||||
float n = snoise(vTexCoord3D);
|
||||
|
||||
gl_FragColor = vec4(0.5 + 0.6 * vec3(n, n, n), 1.0);
|
||||
}
|
||||
|
||||
-- Vertex.flame
|
||||
|
||||
uniform float time;
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vTexCoord3D = gl_Vertex.xyz * 2.0 + vec3(0.0, 0.0, -time);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
-- Fragment.flame
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
void main( void )
|
||||
{
|
||||
float n = abs(snoise(vTexCoord3D));
|
||||
n += 0.5 * abs(snoise(vTexCoord3D * 2.0));
|
||||
n += 0.25 * abs(snoise(vTexCoord3D * 4.0));
|
||||
n += 0.125 * abs(snoise(vTexCoord3D * 8.0));
|
||||
|
||||
gl_FragColor = vec4(vec3(1.5-n, 1.0-n, 0.5-n), 1.0);
|
||||
}
|
||||
|
||||
-- Noise.flow
|
||||
|
||||
// GLSL implementation of 2D "flow noise" as presented
|
||||
// by Ken Perlin and Fabrice Neyret at Siggraph 2001.
|
||||
// (2D simplex noise with analytic derivatives and
|
||||
// in-plane rotation of generating gradients,
|
||||
// in a fractal sum where higher frequencies are
|
||||
// displaced (advected) by lower frequencies in the
|
||||
// direction of their gradient. For details, please
|
||||
// refer to the 2001 paper "Flow Noise" by Perlin and Neyret.)
|
||||
//
|
||||
// Author: Stefan Gustavson (stefan.gustavson@liu.se)
|
||||
// Distributed under the terms of the MIT license.
|
||||
// See LICENSE file for details.
|
||||
//
|
||||
|
||||
// Helper constants
|
||||
#define F2 0.366025403
|
||||
#define G2 0.211324865
|
||||
#define K 0.0243902439 // 1/41
|
||||
|
||||
// Gradient mapping with an extra rotation.
|
||||
vec2 grad2(vec2 p, float rot) {
|
||||
#if 1
|
||||
// Map from a line to a diamond such that a shift maps to a rotation.
|
||||
float u = permute(permute(p.x) + p.y) * K + rot; // Rotate by shift
|
||||
u = 4.0 * fract(u) - 2.0;
|
||||
return vec2(abs(u)-1.0, abs(abs(u+1.0)-2.0)-1.0);
|
||||
#else
|
||||
#define TWOPI 6.28318530718
|
||||
// For more isotropic gradients, sin/cos can be used instead.
|
||||
float u = permute(permute(p.x) + p.y) * K + rot; // Rotate by shift
|
||||
u = fract(u) * TWOPI;
|
||||
return vec2(cos(u), sin(u));
|
||||
#endif
|
||||
}
|
||||
|
||||
float srdnoise(in vec2 P, in float rot, out vec2 grad) {
|
||||
|
||||
// Transform input point to the skewed simplex grid
|
||||
vec2 Ps = P + dot(P, vec2(F2));
|
||||
|
||||
// Round down to simplex origin
|
||||
vec2 Pi = floor(Ps);
|
||||
|
||||
// Transform simplex origin back to (x,y) system
|
||||
vec2 P0 = Pi - dot(Pi, vec2(G2));
|
||||
|
||||
// Find (x,y) offsets from simplex origin to first corner
|
||||
vec2 v0 = P - P0;
|
||||
|
||||
// Pick (+x, +y) or (+y, +x) increment sequence
|
||||
vec2 i1 = (v0.x > v0.y) ? vec2(1.0, 0.0) : vec2 (0.0, 1.0);
|
||||
|
||||
// Determine the offsets for the other two corners
|
||||
vec2 v1 = v0 - i1 + G2;
|
||||
vec2 v2 = v0 - 1.0 + 2.0 * G2;
|
||||
|
||||
// Wrap coordinates at 289 to avoid float precision problems
|
||||
Pi = mod(Pi, 289.0);
|
||||
|
||||
// Calculate the circularly symmetric part of each noise wiggle
|
||||
vec3 t = max(0.5 - vec3(dot(v0,v0), dot(v1,v1), dot(v2,v2)), 0.0);
|
||||
vec3 t2 = t*t;
|
||||
vec3 t4 = t2*t2;
|
||||
|
||||
// Calculate the gradients for the three corners
|
||||
vec2 g0 = grad2(Pi, rot);
|
||||
vec2 g1 = grad2(Pi + i1, rot);
|
||||
vec2 g2 = grad2(Pi + 1.0, rot);
|
||||
|
||||
// Compute noise contributions from each corner
|
||||
vec3 gv = vec3(dot(g0,v0), dot(g1,v1), dot(g2,v2)); // ramp: g dot v
|
||||
vec3 n = t4 * gv; // Circular kernel times linear ramp
|
||||
|
||||
// Compute partial derivatives in x and y
|
||||
vec3 temp = t2 * t * gv;
|
||||
vec3 gradx = temp * vec3(v0.x, v1.x, v2.x);
|
||||
vec3 grady = temp * vec3(v0.y, v1.y, v2.y);
|
||||
grad.x = -8.0 * (gradx.x + gradx.y + gradx.z);
|
||||
grad.y = -8.0 * (grady.x + grady.y + grady.z);
|
||||
grad.x += dot(t4, vec3(g0.x, g1.x, g2.x));
|
||||
grad.y += dot(t4, vec3(g0.y, g1.y, g2.y));
|
||||
grad *= 40.0;
|
||||
|
||||
// Add contributions from the three corners and return
|
||||
return 40.0 * (n.x + n.y + n.z);
|
||||
}
|
||||
|
||||
-- Vertex.flow
|
||||
|
||||
varying vec2 vTexCoord2D;
|
||||
|
||||
void main(void) {
|
||||
vTexCoord2D = gl_Vertex.xy * 8.0;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
-- Fragment.flow
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
uniform float time;
|
||||
|
||||
void main(void) {
|
||||
vec2 g1, g2;
|
||||
vec2 p = vTexCoord2D;
|
||||
float n1 = srdnoise(p*0.5, 0.2*time, g1);
|
||||
float n2 = srdnoise(p*2.0 + g1*0.5, 0.51*time, g2);
|
||||
float n3 = srdnoise(p*4.0 + g1*0.5 + g2*0.25, 0.77*time, g2);
|
||||
gl_FragColor = vec4(vec3(0.4, 0.5, 0.6) + vec3(n1+0.75*n2+0.5*n3), 1.0);
|
||||
}
|
||||
|
||||
-- Noise.spots
|
||||
|
||||
// Cellular noise ("Worley noise") in 3D in GLSL.
|
||||
// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.
|
||||
// This code is released under the conditions of the MIT license.
|
||||
// See LICENSE file for details.
|
||||
|
||||
// Cellular noise, returning F1 and F2 in a vec2.
|
||||
// Speeded up by using 2x2x2 search window instead of 3x3x3,
|
||||
// at the expense of some pattern artifacts.
|
||||
// F2 is often wrong and has sharp discontinuities.
|
||||
// If you need a good F2, use the slower 3x3x3 version.
|
||||
vec2 cellular2x2x2(vec3 P)
|
||||
{
|
||||
#define K 0.142857142857 // 1/7
|
||||
#define Ko 0.428571428571 // 1/2-K/2
|
||||
#define K2 0.020408163265306 // 1/(7*7)
|
||||
#define Kz 0.166666666667 // 1/6
|
||||
#define Kzo 0.416666666667 // 1/2-1/6*2
|
||||
#define jitter 0.8 // smaller jitter gives less errors in F2
|
||||
vec3 Pi = mod(floor(P), 289.0);
|
||||
vec3 Pf = fract(P);
|
||||
vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0);
|
||||
vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0);
|
||||
vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));
|
||||
p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));
|
||||
vec4 p1 = permute(p + Pi.z); // z+0
|
||||
vec4 p2 = permute(p + Pi.z + vec4(1.0)); // z+1
|
||||
vec4 ox1 = fract(p1*K) - Ko;
|
||||
vec4 oy1 = mod(floor(p1*K), 7.0)*K - Ko;
|
||||
vec4 oz1 = floor(p1*K2)*Kz - Kzo; // p1 < 289 guaranteed
|
||||
vec4 ox2 = fract(p2*K) - Ko;
|
||||
vec4 oy2 = mod(floor(p2*K), 7.0)*K - Ko;
|
||||
vec4 oz2 = floor(p2*K2)*Kz - Kzo;
|
||||
vec4 dx1 = Pfx + jitter*ox1;
|
||||
vec4 dy1 = Pfy + jitter*oy1;
|
||||
vec4 dz1 = Pf.z + jitter*oz1;
|
||||
vec4 dx2 = Pfx + jitter*ox2;
|
||||
vec4 dy2 = Pfy + jitter*oy2;
|
||||
vec4 dz2 = Pf.z - 1.0 + jitter*oz2;
|
||||
vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; // z+0
|
||||
vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2; // z+1
|
||||
|
||||
// Sort out the two smallest distances (F1, F2)
|
||||
#if 1
|
||||
// Cheat and sort out only F1
|
||||
d1 = min(d1, d2);
|
||||
d1.xy = min(d1.xy, d1.wz);
|
||||
d1.x = min(d1.x, d1.y);
|
||||
return sqrt(d1.xx);
|
||||
#else
|
||||
// Do it right and sort out both F1 and F2
|
||||
vec4 d = min(d1,d2); // F1 is now in d
|
||||
d2 = max(d1,d2); // Make sure we keep all candidates for F2
|
||||
d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap smallest to d.x
|
||||
d.xz = (d.x < d.z) ? d.xz : d.zx;
|
||||
d.xw = (d.x < d.w) ? d.xw : d.wx; // F1 is now in d.x
|
||||
d.yzw = min(d.yzw, d2.yzw); // F2 now not in d2.yzw
|
||||
d.y = min(d.y, d.z); // nor in d.z
|
||||
d.y = min(d.y, d.w); // nor in d.w
|
||||
d.y = min(d.y, d2.x); // F2 is now in d.y
|
||||
return sqrt(d.xy); // F1 and F2
|
||||
#endif
|
||||
}
|
||||
|
||||
-- Vertex.spots
|
||||
|
||||
uniform float time;
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vTexCoord3D = gl_Vertex.xyz * 4.0 - vec3(0.0, 0.0, time);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
-- Fragment.spots
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vec2 F = cellular2x2x2(vTexCoord3D);
|
||||
float s = fwidth(F.x);
|
||||
float n1 = smoothstep(0.4-s, 0.4+s, F.x);
|
||||
float n2 = smoothstep(0.5-s, 0.5+s, F.x);
|
||||
gl_FragColor = vec4(n1, n2, n2, 1.0);
|
||||
}
|
||||
|
||||
-- Noise.tile
|
||||
|
||||
// Cellular noise ("Worley noise") in 3D in GLSL.
|
||||
// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.
|
||||
// This code is released under the conditions of the MIT license.
|
||||
// See LICENSE file for details.
|
||||
|
||||
// Cellular noise, returning F1 and F2 in a vec2.
|
||||
// 3x3x3 search region for good F2 everywhere, but a lot
|
||||
// slower than the 2x2x2 version.
|
||||
// The code below is a bit scary even to its author,
|
||||
// but it has at least half decent performance on a
|
||||
// modern GPU. In any case, it beats any software
|
||||
// implementation of Worley noise hands down.
|
||||
|
||||
vec2 cellular(vec3 P)
|
||||
{
|
||||
#define K 0.142857142857 // 1/7
|
||||
#define Ko 0.428571428571 // 1/2-K/2
|
||||
#define K2 0.020408163265306 // 1/(7*7)
|
||||
#define Kz 0.166666666667 // 1/6
|
||||
#define Kzo 0.416666666667 // 1/2-1/6*2
|
||||
#define jitter 1.0 // smaller jitter gives more regular pattern
|
||||
|
||||
vec3 Pi = mod(floor(P), 289.0);
|
||||
vec3 Pf = fract(P) - 0.5;
|
||||
|
||||
vec3 Pfx = Pf.x + vec3(1.0, 0.0, -1.0);
|
||||
vec3 Pfy = Pf.y + vec3(1.0, 0.0, -1.0);
|
||||
vec3 Pfz = Pf.z + vec3(1.0, 0.0, -1.0);
|
||||
|
||||
vec3 p = permute(Pi.x + vec3(-1.0, 0.0, 1.0));
|
||||
vec3 p1 = permute(p + Pi.y - 1.0);
|
||||
vec3 p2 = permute(p + Pi.y);
|
||||
vec3 p3 = permute(p + Pi.y + 1.0);
|
||||
|
||||
vec3 p11 = permute(p1 + Pi.z - 1.0);
|
||||
vec3 p12 = permute(p1 + Pi.z);
|
||||
vec3 p13 = permute(p1 + Pi.z + 1.0);
|
||||
|
||||
vec3 p21 = permute(p2 + Pi.z - 1.0);
|
||||
vec3 p22 = permute(p2 + Pi.z);
|
||||
vec3 p23 = permute(p2 + Pi.z + 1.0);
|
||||
|
||||
vec3 p31 = permute(p3 + Pi.z - 1.0);
|
||||
vec3 p32 = permute(p3 + Pi.z);
|
||||
vec3 p33 = permute(p3 + Pi.z + 1.0);
|
||||
|
||||
vec3 ox11 = fract(p11*K) - Ko;
|
||||
vec3 oy11 = mod(floor(p11*K), 7.0)*K - Ko;
|
||||
vec3 oz11 = floor(p11*K2)*Kz - Kzo; // p11 < 289 guaranteed
|
||||
|
||||
vec3 ox12 = fract(p12*K) - Ko;
|
||||
vec3 oy12 = mod(floor(p12*K), 7.0)*K - Ko;
|
||||
vec3 oz12 = floor(p12*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox13 = fract(p13*K) - Ko;
|
||||
vec3 oy13 = mod(floor(p13*K), 7.0)*K - Ko;
|
||||
vec3 oz13 = floor(p13*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox21 = fract(p21*K) - Ko;
|
||||
vec3 oy21 = mod(floor(p21*K), 7.0)*K - Ko;
|
||||
vec3 oz21 = floor(p21*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox22 = fract(p22*K) - Ko;
|
||||
vec3 oy22 = mod(floor(p22*K), 7.0)*K - Ko;
|
||||
vec3 oz22 = floor(p22*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox23 = fract(p23*K) - Ko;
|
||||
vec3 oy23 = mod(floor(p23*K), 7.0)*K - Ko;
|
||||
vec3 oz23 = floor(p23*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox31 = fract(p31*K) - Ko;
|
||||
vec3 oy31 = mod(floor(p31*K), 7.0)*K - Ko;
|
||||
vec3 oz31 = floor(p31*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox32 = fract(p32*K) - Ko;
|
||||
vec3 oy32 = mod(floor(p32*K), 7.0)*K - Ko;
|
||||
vec3 oz32 = floor(p32*K2)*Kz - Kzo;
|
||||
|
||||
vec3 ox33 = fract(p33*K) - Ko;
|
||||
vec3 oy33 = mod(floor(p33*K), 7.0)*K - Ko;
|
||||
vec3 oz33 = floor(p33*K2)*Kz - Kzo;
|
||||
|
||||
vec3 dx11 = Pfx + jitter*ox11;
|
||||
vec3 dy11 = Pfy.x + jitter*oy11;
|
||||
vec3 dz11 = Pfz.x + jitter*oz11;
|
||||
|
||||
vec3 dx12 = Pfx + jitter*ox12;
|
||||
vec3 dy12 = Pfy.x + jitter*oy12;
|
||||
vec3 dz12 = Pfz.y + jitter*oz12;
|
||||
|
||||
vec3 dx13 = Pfx + jitter*ox13;
|
||||
vec3 dy13 = Pfy.x + jitter*oy13;
|
||||
vec3 dz13 = Pfz.z + jitter*oz13;
|
||||
|
||||
vec3 dx21 = Pfx + jitter*ox21;
|
||||
vec3 dy21 = Pfy.y + jitter*oy21;
|
||||
vec3 dz21 = Pfz.x + jitter*oz21;
|
||||
|
||||
vec3 dx22 = Pfx + jitter*ox22;
|
||||
vec3 dy22 = Pfy.y + jitter*oy22;
|
||||
vec3 dz22 = Pfz.y + jitter*oz22;
|
||||
|
||||
vec3 dx23 = Pfx + jitter*ox23;
|
||||
vec3 dy23 = Pfy.y + jitter*oy23;
|
||||
vec3 dz23 = Pfz.z + jitter*oz23;
|
||||
|
||||
vec3 dx31 = Pfx + jitter*ox31;
|
||||
vec3 dy31 = Pfy.z + jitter*oy31;
|
||||
vec3 dz31 = Pfz.x + jitter*oz31;
|
||||
|
||||
vec3 dx32 = Pfx + jitter*ox32;
|
||||
vec3 dy32 = Pfy.z + jitter*oy32;
|
||||
vec3 dz32 = Pfz.y + jitter*oz32;
|
||||
|
||||
vec3 dx33 = Pfx + jitter*ox33;
|
||||
vec3 dy33 = Pfy.z + jitter*oy33;
|
||||
vec3 dz33 = Pfz.z + jitter*oz33;
|
||||
|
||||
vec3 d11 = dx11 * dx11 + dy11 * dy11 + dz11 * dz11;
|
||||
vec3 d12 = dx12 * dx12 + dy12 * dy12 + dz12 * dz12;
|
||||
vec3 d13 = dx13 * dx13 + dy13 * dy13 + dz13 * dz13;
|
||||
vec3 d21 = dx21 * dx21 + dy21 * dy21 + dz21 * dz21;
|
||||
vec3 d22 = dx22 * dx22 + dy22 * dy22 + dz22 * dz22;
|
||||
vec3 d23 = dx23 * dx23 + dy23 * dy23 + dz23 * dz23;
|
||||
vec3 d31 = dx31 * dx31 + dy31 * dy31 + dz31 * dz31;
|
||||
vec3 d32 = dx32 * dx32 + dy32 * dy32 + dz32 * dz32;
|
||||
vec3 d33 = dx33 * dx33 + dy33 * dy33 + dz33 * dz33;
|
||||
|
||||
// Sort out the two smallest distances (F1, F2)
|
||||
#if 0
|
||||
// Cheat and sort out only F1
|
||||
vec3 d1 = min(min(d11,d12), d13);
|
||||
vec3 d2 = min(min(d21,d22), d23);
|
||||
vec3 d3 = min(min(d31,d32), d33);
|
||||
vec3 d = min(min(d1,d2), d3);
|
||||
d.x = min(min(d.x,d.y),d.z);
|
||||
return sqrt(d.xx); // F1 duplicated, no F2 computed
|
||||
#else
|
||||
// Do it right and sort out both F1 and F2
|
||||
vec3 d1a = min(d11, d12);
|
||||
d12 = max(d11, d12);
|
||||
d11 = min(d1a, d13); // Smallest now not in d12 or d13
|
||||
d13 = max(d1a, d13);
|
||||
d12 = min(d12, d13); // 2nd smallest now not in d13
|
||||
vec3 d2a = min(d21, d22);
|
||||
d22 = max(d21, d22);
|
||||
d21 = min(d2a, d23); // Smallest now not in d22 or d23
|
||||
d23 = max(d2a, d23);
|
||||
d22 = min(d22, d23); // 2nd smallest now not in d23
|
||||
vec3 d3a = min(d31, d32);
|
||||
d32 = max(d31, d32);
|
||||
d31 = min(d3a, d33); // Smallest now not in d32 or d33
|
||||
d33 = max(d3a, d33);
|
||||
d32 = min(d32, d33); // 2nd smallest now not in d33
|
||||
vec3 da = min(d11, d21);
|
||||
d21 = max(d11, d21);
|
||||
d11 = min(da, d31); // Smallest now in d11
|
||||
d31 = max(da, d31); // 2nd smallest now not in d31
|
||||
d11.xy = (d11.x < d11.y) ? d11.xy : d11.yx;
|
||||
d11.xz = (d11.x < d11.z) ? d11.xz : d11.zx; // d11.x now smallest
|
||||
d12 = min(d12, d21); // 2nd smallest now not in d21
|
||||
d12 = min(d12, d22); // nor in d22
|
||||
d12 = min(d12, d31); // nor in d31
|
||||
d12 = min(d12, d32); // nor in d32
|
||||
d11.yz = min(d11.yz,d12.xy); // nor in d12.yz
|
||||
d11.y = min(d11.y,d12.z); // Only two more to go
|
||||
d11.y = min(d11.y,d11.z); // Done! (Phew!)
|
||||
return sqrt(d11.xy); // F1, F2
|
||||
#endif
|
||||
}
|
||||
|
||||
-- Vertex.tile
|
||||
|
||||
uniform float time;
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vTexCoord3D = gl_Vertex.xyz * 4.0
|
||||
+ 0.2 * vec3(snoise(gl_Vertex.xyz + vec3(0.0, 0.0, time)),
|
||||
snoise(gl_Vertex.xyz + vec3(43.0, 17.0, time)),
|
||||
snoise(gl_Vertex.xyz + vec3(0.0, -43.0, time-17.0)));
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
-- Fragment.tile
|
||||
|
||||
varying vec3 vTexCoord3D;
|
||||
|
||||
void main(void) {
|
||||
vec2 F = cellular(vTexCoord3D.xyz);
|
||||
float n = 0.1+F.y-F.x;
|
||||
gl_FragColor = vec4(n*0.6, n*1.1, n*0.5, 1.0);
|
||||
}
|
|
@ -57,6 +57,11 @@
|
|||
|
||||
static const char quakeforge_effect[] =
|
||||
#include "libs/video/renderer/glsl/quakeforge.slc"
|
||||
"--\n" // ensure the last block of the previous file doesn't merge with
|
||||
// the first block of the next file
|
||||
// Include Stefan Gustavson's noise functions in the QuakeForge shader
|
||||
// effect "file".
|
||||
#include "libs/video/renderer/glsl/sgustavson.slc"
|
||||
;
|
||||
|
||||
int glsl_palette;
|
||||
|
|
|
@ -614,4 +614,5 @@ R_Init_Cvars (void)
|
|||
r_data->scr_viewsize = &scr_viewsize;
|
||||
|
||||
R_Particles_Init_Cvars ();
|
||||
R_Trails_Init_Cvars ();
|
||||
}
|
||||
|
|
|
@ -105,4 +105,5 @@ R_Init (void)
|
|||
r_funcs->R_Init ();
|
||||
R_ClearEfrags (); //FIXME force link of r_efrag.o for qwaq
|
||||
Fog_Init ();
|
||||
R_Trails_Init ();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
|
@ -135,6 +134,7 @@ R_RunParticles (float dT)
|
|||
p->pos += dT * p->vel;
|
||||
p->vel += dT * (p->vel * parm->drag + gravity * parm->drag[3]);
|
||||
p->ramp += dT * parm->ramp;
|
||||
p->scale += dT * parm->scale_rate;
|
||||
p->live -= dT;
|
||||
if (ramp) {
|
||||
p->icolor = ramp[(int)p->ramp];
|
||||
|
|
|
@ -190,6 +190,9 @@ render_scene (void)
|
|||
EntQueue_Clear (r_ent_queue);
|
||||
r_funcs->render_view ();
|
||||
r_funcs->draw_particles (&r_psystem);
|
||||
if (r_funcs->draw_trails) {
|
||||
r_funcs->draw_trails (&r_tsystem);
|
||||
}
|
||||
r_funcs->draw_transparent ();
|
||||
}
|
||||
|
||||
|
|
236
libs/video/renderer/r_trails.c
Normal file
236
libs/video/renderer/r_trails.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
r_trails.c
|
||||
|
||||
Interface for trails
|
||||
|
||||
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/ecs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/simd/vec4f.h"
|
||||
|
||||
#include "r_dynamic.h"
|
||||
|
||||
psystem_t r_tsystem; //FIXME singleton
|
||||
static ecs_system_t trails_system;
|
||||
static trailpnt_t *trail_point_buffer;
|
||||
static uint32_t trail_point_count;
|
||||
static uint32_t trail_point_buffer_size;
|
||||
static uint32_t allocated_blocks; // bitmask of 64-point blocks in use
|
||||
|
||||
typedef struct {
|
||||
uint32_t base;
|
||||
uint32_t count;
|
||||
} pointset_t;
|
||||
|
||||
enum trails_components {
|
||||
trails_pointset,
|
||||
|
||||
trails_comp_count
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_pointset (void *comp)
|
||||
{
|
||||
pointset_t *pointset = comp;
|
||||
int base = pointset->base / 64;
|
||||
int count = pointset->count / 64;
|
||||
uint32_t mask = ((1 << count) - 1) << base;
|
||||
allocated_blocks &= ~mask;
|
||||
r_tsystem.numparticles = allocated_blocks;
|
||||
}
|
||||
|
||||
static const component_t trails_components[trails_comp_count] = {
|
||||
[trails_pointset] = {
|
||||
.size = sizeof (pointset_t),
|
||||
.create = 0,
|
||||
.name = "pointset",
|
||||
.destroy = destroy_pointset,
|
||||
},
|
||||
};
|
||||
|
||||
bool
|
||||
R_Trail_Valid (psystem_t *system, uint32_t trailid)
|
||||
{
|
||||
return ECS_EntValid (trailid, trails_system.reg);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
R_Trail_Create (psystem_t *system, int num_points, vec4f_t start)
|
||||
{
|
||||
num_points += 2; // need an extra point at either end
|
||||
num_points = (num_points + 31) & ~31; // want a multiple of 32
|
||||
num_points *= 2; // each point needs two verts
|
||||
|
||||
int blocks = num_points / 64;
|
||||
uint32_t mask = (1 << blocks) - 1;
|
||||
int block_ind;
|
||||
for (block_ind = 0; block_ind <= 32 - blocks; block_ind++) {
|
||||
if (!(allocated_blocks & mask)) {
|
||||
break;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
if (allocated_blocks & mask) {
|
||||
return nullent;
|
||||
}
|
||||
allocated_blocks |= mask;
|
||||
r_tsystem.numparticles = allocated_blocks;
|
||||
|
||||
uint32_t trail = ECS_NewEntity (trails_system.reg);
|
||||
pointset_t pointset = {
|
||||
.base = block_ind * 64,
|
||||
.count = num_points,
|
||||
};
|
||||
Ent_SetComponent (trail, trails_pointset, trails_system.reg, &pointset);
|
||||
for (uint32_t i = 0; i < pointset.count; i++) {
|
||||
static float bary[] = {0, 0, 1, 0, 0, 1, 0, 0};
|
||||
auto p = trail_point_buffer + pointset.base + i;
|
||||
*p = (trailpnt_t) {
|
||||
.pos = start,
|
||||
.colora = { 0xc0, 0xa0, 0x60, 0x80 },
|
||||
.colorb = { 0x30, 0x30, 0x20, 0x00 },
|
||||
.trailid = trail,
|
||||
.live = 10,
|
||||
};
|
||||
p->pos[3] = i & 1 ? 1 : -1;
|
||||
VectorCopy (bary + i % 3, p->bary);
|
||||
};
|
||||
return trail;
|
||||
}
|
||||
|
||||
void
|
||||
R_Trail_Update (psystem_t *system, uint32_t trailid, vec4f_t pos)
|
||||
{
|
||||
pointset_t *p = Ent_GetComponent (trailid, trails_pointset,
|
||||
trails_system.reg);
|
||||
|
||||
trailpnt_t *points = trail_point_buffer + p->base;
|
||||
|
||||
pos[3] = -1;
|
||||
vec4f_t dist = pos - points[4].pos;
|
||||
vec4f_t prev1 = points[2].pos;
|
||||
vec4f_t prev2 = points[3].pos;
|
||||
points[2].pos = pos;
|
||||
pos[3] = 1;
|
||||
points[3].pos = pos;
|
||||
|
||||
points[0].pos = points[2].pos + dist;
|
||||
points[1].pos = points[3].pos + dist;
|
||||
|
||||
float len = sqrt (dotf (dist, dist)[0]);
|
||||
if (len > 16) {
|
||||
for (uint32_t i = 4; i < p->count; i += 2) {
|
||||
vec4f_t t1 = points[i + 0].pos;
|
||||
vec4f_t t2 = points[i + 1].pos;
|
||||
points[i + 0].pos = prev1;
|
||||
points[i + 1].pos = prev2;
|
||||
prev1 = t1;
|
||||
prev2 = t2;
|
||||
|
||||
points[i + 0].pathoffset = len;
|
||||
points[i + 1].pathoffset = len;
|
||||
if (i < p->count - 2) {
|
||||
dist = points[i + 2].pos - points[i + 0].pos;
|
||||
len = sqrt (dotf (dist, dist)[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 4; i < p->count; i += 2) {
|
||||
points[i + 0].pathoffset = len;
|
||||
points[i + 1].pathoffset = len;
|
||||
if (i < p->count - 2) {
|
||||
dist = points[i + 2].pos - points[i + 0].pos;
|
||||
len = sqrt (dotf (dist, dist)[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_Trail_Destroy (psystem_t *system, uint32_t trailid)
|
||||
{
|
||||
ECS_DelEntity (trails_system.reg, trailid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_ClearTrails (void)
|
||||
{
|
||||
auto reg = trails_system.reg;
|
||||
for (uint32_t i = 0; i < reg->num_entities; i++) {
|
||||
uint32_t ent = reg->entities[i];
|
||||
uint32_t ind = Ent_Index (ent);
|
||||
if (ind == i) {
|
||||
ECS_DelEntity (reg, ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_RunTrails (float dT)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
R_Trails_Init_Cvars (void)
|
||||
{
|
||||
Sys_Printf ("R_Trails_Init_Cvars\n");
|
||||
}
|
||||
|
||||
static void
|
||||
trails_shutdown (void *data)
|
||||
{
|
||||
Sys_Printf ("trails_shutdown\n");
|
||||
ECS_DelRegistry (trails_system.reg);
|
||||
Sys_Free (trail_point_buffer, trail_point_buffer_size);
|
||||
}
|
||||
|
||||
void
|
||||
R_Trails_Init (void)
|
||||
{
|
||||
Sys_Printf ("R_Trails_Init\n");
|
||||
Sys_RegisterShutdown (trails_shutdown, 0);
|
||||
auto reg = ECS_NewRegistry ();
|
||||
trails_system.reg = reg;
|
||||
trails_system.base = ECS_RegisterComponents (reg, trails_components,
|
||||
trails_comp_count);
|
||||
ECS_CreateComponentPools (reg);
|
||||
|
||||
trail_point_count = 32*64;
|
||||
trail_point_buffer_size = trail_point_count * sizeof (trailpnt_t);
|
||||
trail_point_buffer = Sys_Alloc (trail_point_buffer_size);
|
||||
|
||||
r_tsystem = (psystem_t) {
|
||||
.maxparticles = trail_point_count,
|
||||
.particles = (particle_t *) trail_point_buffer,
|
||||
.partparams = 0,//FIXME
|
||||
.partramps = 0,//FIXME
|
||||
};
|
||||
}
|
|
@ -477,6 +477,7 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
.Draw_Glyph = glsl_Draw_Glyph,
|
||||
|
||||
.ParticleSystem = glsl_ParticleSystem,
|
||||
.TrailSystem = glsl_TrailSystem,
|
||||
.R_Init = glsl_R_Init,
|
||||
.R_ClearState = glsl_R_ClearState,
|
||||
.R_LoadSkys = glsl_R_LoadSkys,
|
||||
|
@ -485,6 +486,7 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
.begin_frame = glsl_begin_frame,
|
||||
.render_view = glsl_render_view,
|
||||
.draw_particles = glsl_R_DrawParticles,
|
||||
.draw_trails = glsl_R_DrawTrails,
|
||||
.draw_transparent = glsl_draw_transparent,
|
||||
.post_process = glsl_post_process,
|
||||
.set_2d = glsl_set_2d,
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "compat.h"
|
||||
|
||||
#include "client/chase.h"
|
||||
#include "client/effects.h"
|
||||
#include "client/particles.h"
|
||||
#include "client/sbar.h"
|
||||
#include "client/screen.h"
|
||||
|
@ -740,6 +741,7 @@ CL_Init (cbuf_t *cbuf)
|
|||
|
||||
CL_Init_Input (cbuf);
|
||||
CL_Particles_Init ();
|
||||
CL_Effects_Init ();
|
||||
CL_TEnts_Init ();
|
||||
CL_World_Init ();
|
||||
CL_ClearState ();
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
#include "buildnum.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
#include "client/particles.h"
|
||||
#include "client/sbar.h"
|
||||
#include "client/screen.h"
|
||||
|
@ -1488,6 +1489,7 @@ CL_Init (void)
|
|||
CL_Init_Input (cl_cbuf);
|
||||
CL_Ents_Init ();
|
||||
CL_Particles_Init ();
|
||||
CL_Effects_Init ();
|
||||
CL_TEnts_Init ();
|
||||
CL_World_Init ();
|
||||
CL_ClearState ();
|
||||
|
|
Loading…
Reference in a new issue