Copy as Markdown

Other Tools

struct cs_line_decoration_common {
struct Samplers {
bool set_slot(int index, int value) {
switch (index) {
}
return false;
}
} samplers;
struct AttribLocations {
int aPosition = NULL_ATTRIB;
int aTaskRect = NULL_ATTRIB;
int aLocalSize = NULL_ATTRIB;
int aStyle = NULL_ATTRIB;
int aAxisSelect = NULL_ATTRIB;
int aWavyLineThickness = NULL_ATTRIB;
void bind_loc(const char* name, int index) {
if (strcmp("aPosition", name) == 0) { aPosition = index; return; }
if (strcmp("aTaskRect", name) == 0) { aTaskRect = index; return; }
if (strcmp("aLocalSize", name) == 0) { aLocalSize = index; return; }
if (strcmp("aStyle", name) == 0) { aStyle = index; return; }
if (strcmp("aAxisSelect", name) == 0) { aAxisSelect = index; return; }
if (strcmp("aWavyLineThickness", name) == 0) { aWavyLineThickness = index; return; }
}
int get_loc(const char* name) const {
if (strcmp("aPosition", name) == 0) { return aPosition != NULL_ATTRIB ? aPosition : -1; }
if (strcmp("aTaskRect", name) == 0) { return aTaskRect != NULL_ATTRIB ? aTaskRect : -1; }
if (strcmp("aLocalSize", name) == 0) { return aLocalSize != NULL_ATTRIB ? aLocalSize : -1; }
if (strcmp("aStyle", name) == 0) { return aStyle != NULL_ATTRIB ? aStyle : -1; }
if (strcmp("aAxisSelect", name) == 0) { return aAxisSelect != NULL_ATTRIB ? aAxisSelect : -1; }
if (strcmp("aWavyLineThickness", name) == 0) { return aWavyLineThickness != NULL_ATTRIB ? aWavyLineThickness : -1; }
return -1;
}
} attrib_locations;
ivec2_scalar vStyle;
vec4_scalar vParams;
mat4_scalar uTransform;
void bind_textures() {
}
};
struct cs_line_decoration_vert : VertexShaderImpl, cs_line_decoration_common {
private:
typedef cs_line_decoration_vert Self;
// mat4_scalar uTransform;
vec2 aPosition;
vec2 vLocalPos;
// ivec2_scalar vStyle;
// vec4_scalar vParams;
vec4_scalar aTaskRect;
vec2_scalar aLocalSize;
int32_t aStyle;
float aAxisSelect;
float aWavyLineThickness;
ALWAYS_INLINE void main(void) {
vec2_scalar size = mix(aLocalSize, (aLocalSize).sel(Y,X), aAxisSelect);
(vStyle).x = aStyle;
switch ((vStyle).x) {
case 0:
{
break;
}
case 2:
{
vParams = make_vec4((size).x, (0.5f)*((size).x), 0.f, 0.f);
break;
}
case 1:
{
float diameter = (size).y;
float period = (diameter)*(2.f);
float center_line = (0.5f)*((size).y);
vParams = make_vec4(period, (diameter)/(2.f), center_line, 0.f);
break;
}
case 3:
{
float line_thickness = max(aWavyLineThickness, 1.f);
float slope_length = ((size).y)-(line_thickness);
float flat_length = max(((line_thickness)-(1.f))*(2.f), 1.f);
vParams = make_vec4((line_thickness)/(2.f), slope_length, flat_length, (size).y);
break;
}
default:
vParams = make_vec4(0.f);
}
vLocalPos = (mix((aPosition).sel(X,Y), (aPosition).sel(Y,X), aAxisSelect))*(size);
gl_Position = (uTransform)*(make_vec4(mix((aTaskRect).sel(X,Y), (aTaskRect).sel(Z,W), (aPosition).sel(X,Y)), 0.f, 1.f));
}
static void set_uniform_1i(VertexShaderImpl* impl, int index, int value) {
Self* self = (Self*)impl;
if (self->samplers.set_slot(index, value)) return;
switch (index) {
case 1:
assert(0); // uTransform
break;
}
}
static void set_uniform_4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 1:
assert(0); // uTransform
break;
}
}
static void set_uniform_matrix4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 1:
self->uTransform = mat4_scalar::load_from_ptr(value);
break;
}
}
static void load_attribs(VertexShaderImpl* impl, VertexAttrib *attribs, uint32_t start, int instance, int count) {Self* self = (Self*)impl;
load_attrib(self->aPosition, attribs[self->attrib_locations.aPosition], start, instance, count);
load_flat_attrib(self->aTaskRect, attribs[self->attrib_locations.aTaskRect], start, instance, count);
load_flat_attrib(self->aLocalSize, attribs[self->attrib_locations.aLocalSize], start, instance, count);
load_flat_attrib(self->aStyle, attribs[self->attrib_locations.aStyle], start, instance, count);
load_flat_attrib(self->aAxisSelect, attribs[self->attrib_locations.aAxisSelect], start, instance, count);
load_flat_attrib(self->aWavyLineThickness, attribs[self->attrib_locations.aWavyLineThickness], start, instance, count);
}
public:
struct InterpOutputs {
vec2_scalar vLocalPos;
};
private:
ALWAYS_INLINE void store_interp_outputs(char* dest_ptr, size_t stride) {
for(int n = 0; n < 4; n++) {
auto* dest = reinterpret_cast<InterpOutputs*>(dest_ptr);
dest->vLocalPos = get_nth(vLocalPos, n);
dest_ptr += stride;
}
}
static void run(VertexShaderImpl* impl, char* interps, size_t interp_stride) {
Self* self = (Self*)impl;
self->main();
self->store_interp_outputs(interps, interp_stride);
}
static void init_batch(VertexShaderImpl* impl) {
Self* self = (Self*)impl; self->bind_textures(); }
public:
cs_line_decoration_vert() {
set_uniform_1i_func = &set_uniform_1i;
set_uniform_4fv_func = &set_uniform_4fv;
set_uniform_matrix4fv_func = &set_uniform_matrix4fv;
init_batch_func = &init_batch;
load_attribs_func = &load_attribs;
run_primitive_func = &run;
}
};
struct cs_line_decoration_frag : FragmentShaderImpl, cs_line_decoration_vert {
private:
typedef cs_line_decoration_frag Self;
#define oFragColor gl_FragColor
// vec4 oFragColor;
vec2 vLocalPos;
// ivec2_scalar vStyle;
// vec4_scalar vParams;
float compute_aa_range(vec2 position) {
return recip((fwidth(position)).x);
}
Float distance_aa(float aa_range, Float signed_distance) {
Float dist = (signed_distance)*(aa_range);
return clamp((0.5f)-(dist), 0.f, 1.f);
}
Float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
vec2 dir_to_p0 = (p0)-(p);
return dot(normalize(perp_dir), dir_to_p0);
}
ALWAYS_INLINE void main(void) {
vec2 pos = vLocalPos;
float aa_range = compute_aa_range(pos);
Float alpha = 1.f;
switch ((vStyle).x) {
case 0:
{
break;
}
case 2:
{
alpha = step(floor(((pos).x)+(0.5f)), (vParams).y);
break;
}
case 1:
{
vec2 dot_relative_pos = (pos)-((vParams).sel(Y,Z));
Float dot_distance = (length(dot_relative_pos))-((vParams).y);
alpha = distance_aa(aa_range, dot_distance);
break;
}
case 3:
{
float half_line_thickness = (vParams).x;
float slope_length = (vParams).y;
float flat_length = (vParams).z;
float vertical_bounds = (vParams).w;
float half_period = (slope_length)+(flat_length);
float mid_height = (vertical_bounds)/(2.f);
Float peak_offset = (mid_height)-(half_line_thickness);
Float flip = (-(2.f))*((step(mod((pos).x, (2.f)*(half_period)), half_period))-(0.5f));
peak_offset *= flip;
Float peak_height = (mid_height)+(peak_offset);
(pos).x = mod((pos).x, half_period);
Float dist1 = distance_to_line(make_vec2(0.f, peak_height), make_vec2(1.f, -(flip)), pos);
Float dist2 = distance_to_line(make_vec2(0.f, peak_height), make_vec2(0, -(flip)), pos);
Float dist3 = distance_to_line(make_vec2(flat_length, peak_height), make_vec2(-(1.f), -(flip)), pos);
Float dist = abs(max(max(dist1, dist2), dist3));
alpha = distance_aa(aa_range, (dist)-(half_line_thickness));
if ((half_line_thickness)<=(1.f)) {
{
alpha = (1.f)-(step(alpha, 0.5f));
}
}
break;
}
default:
break;
}
oFragColor = make_vec4(alpha);
}
typedef cs_line_decoration_vert::InterpOutputs InterpInputs;
InterpInputs interp_step;
struct InterpPerspective {
vec2 vLocalPos;
};
InterpPerspective interp_perspective;
static void read_interp_inputs(FragmentShaderImpl* impl, const void* init_, const void* step_) {Self* self = (Self*)impl;const InterpInputs* init = (const InterpInputs*)init_;const InterpInputs* step = (const InterpInputs*)step_;
self->vLocalPos = init_interp(init->vLocalPos, step->vLocalPos);
self->interp_step.vLocalPos = step->vLocalPos * 4.0f;
}
static void read_perspective_inputs(FragmentShaderImpl* impl, const void* init_, const void* step_) {Self* self = (Self*)impl;const InterpInputs* init = (const InterpInputs*)init_;const InterpInputs* step = (const InterpInputs*)step_;
Float w = 1.0f / self->gl_FragCoord.w;
self->interp_perspective.vLocalPos = init_interp(init->vLocalPos, step->vLocalPos);
self->vLocalPos = self->interp_perspective.vLocalPos * w;
self->interp_step.vLocalPos = step->vLocalPos * 4.0f;
}
ALWAYS_INLINE void step_interp_inputs(int steps = 4) {
float chunks = steps * 0.25f;
vLocalPos += interp_step.vLocalPos * chunks;
}
ALWAYS_INLINE void step_perspective_inputs(int steps = 4) {
step_perspective(steps);
float chunks = steps * 0.25f;
Float w = 1.0f / gl_FragCoord.w;
interp_perspective.vLocalPos += interp_step.vLocalPos * chunks;
vLocalPos = w * interp_perspective.vLocalPos;
}
static void run(FragmentShaderImpl* impl) {
Self* self = (Self*)impl;
self->main();
self->step_interp_inputs();
}
static void skip(FragmentShaderImpl* impl, int steps) {
Self* self = (Self*)impl;
self->step_interp_inputs(steps);
}
static void run_perspective(FragmentShaderImpl* impl) {
Self* self = (Self*)impl;
self->main();
self->step_perspective_inputs();
}
static void skip_perspective(FragmentShaderImpl* impl, int steps) {
Self* self = (Self*)impl;
self->step_perspective_inputs(steps);
}
public:
cs_line_decoration_frag() {
init_span_func = &read_interp_inputs;
run_func = &run;
skip_func = &skip;
enable_perspective();
init_span_w_func = &read_perspective_inputs;
run_w_func = &run_perspective;
skip_w_func = &skip_perspective;
}
};
struct cs_line_decoration_program : ProgramImpl, cs_line_decoration_frag {
int get_uniform(const char *name) const override {
if (strcmp("uTransform", name) == 0) { return 1; }
return -1;
}
void bind_attrib(const char* name, int index) override {
attrib_locations.bind_loc(name, index);
}
int get_attrib(const char* name) const override {
return attrib_locations.get_loc(name);
}
size_t interpolants_size() const override { return sizeof(InterpOutputs); }
VertexShaderImpl* get_vertex_shader() override {
return this;
}
FragmentShaderImpl* get_fragment_shader() override {
return this;
}
const char* get_name() const override { return "cs_line_decoration"; }
static ProgramImpl* loader() { return new cs_line_decoration_program; }
};