[add] Added a template of programs for shapes.

This commit is contained in:
falsycat 2019-10-15 00:00:00 +00:00
parent bba4cf5765
commit f2703bda59
3 changed files with 153 additions and 253 deletions

View File

@ -8,23 +8,12 @@ import gl4d;
import sjplayer.ElementDrawer, import sjplayer.ElementDrawer,
sjplayer.ElementInterface, sjplayer.ElementInterface,
sjplayer.ShapeElementProgram,
sjplayer.util.linalg; sjplayer.util.linalg;
/// ///
class CircleElement : ElementInterface { class CircleElement : ElementInterface {
public: public:
///
static struct Instance {
///
align(1) mat3 matrix = mat3.identity;
///
align(1) float weight = 1;
///
align(1) float smooth = 0.001;
///
align(1) vec4 color = vec4(0, 0, 0, 0);
}
/// ///
void Initialize() { void Initialize() {
alive = false; alive = false;
@ -54,7 +43,7 @@ class CircleElement : ElementInterface {
/// ///
float nearness_coe; float nearness_coe;
/// ///
Instance instance; CircleElementProgram.Instance instance;
alias instance this; alias instance this;
} }
@ -65,123 +54,10 @@ alias CircleElementDrawer = ElementDrawer!(
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]); [vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
/// ///
class CircleElementProgram { alias CircleElementProgram = ShapeElementProgram!(q{
public:
///
enum ShaderHeader = "#version 330 core
#extension GL_ARB_explicit_uniform_location : enable";
///
enum VertexShaderSrc = ShaderHeader ~ q{
layout(location = 0) in vec2 vert;
layout(location = 1) in vec3 m1;
layout(location = 2) in vec3 m2;
layout(location = 3) in vec3 m3;
layout(location = 4) in float weight;
layout(location = 5) in float smoooth; // expected wrong spell
layout(location = 6) in vec4 color;
out vec2 uv_;
out float weight_;
out float smooth_;
out vec4 color_;
void main() {
mat3 m = transpose(mat3(m1, m2, m3));
vec2 pos = (m * vec3(vert, 1)).xy;
uv_ = vert;
weight_ = weight;
smooth_ = smoooth;
color_ = color;
gl_Position = vec4(pos, 0, 1);
}
};
///
enum FragmentShaderSrc = ShaderHeader ~ q{
in vec2 uv_;
in float weight_;
in float smooth_;
in vec4 color_;
out vec4 pixel_;
float circle() {
float r = length(uv_); float r = length(uv_);
float w = 1 - weight_; float w = 1 - weight_;
return return
smoothstep(w-smooth_, w, r) * smoothstep(w-smooth_, w, r) *
(1 - smoothstep(1-smooth_, 1, r)); (1 - smoothstep(1-smooth_, 1, r));
} });
void main() {
pixel_ = color_;
pixel_.a *= circle();
}
};
///
this() {
ProgramLinker linker;
linker.vertex = VertexShader.Compile(VertexShaderSrc);
linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
program_ = linker.Link();
program_.Validate();
}
///
void SetupVertexArray(ref VertexArrayRef vao,
ref ArrayBufferRef verts, ref ArrayBufferRef instances) {
with (VertexArrayAttacher()) {
// verts
type = GL_FLOAT;
dimension = 2;
Attach(vao, verts);
++index;
type = GL_FLOAT;
divisor = 1;
stride = CircleElement.Instance.sizeof;
offset = 0;
// matrix
dimension = 3;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
// weight
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// smooth
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// color
dimension = 4;
Attach(vao, instances);
offset += float.sizeof*4;
++index;
}
}
///
void Use() {
program_.Use();
}
private:
ProgramRef program_;
}

View File

@ -0,0 +1,136 @@
/// License: MIT
module sjplayer.ShapeElementProgram;
import std.string;
import gl4d;
///
class ShapeElementProgram(string ShaderSrc) {
public:
///
static struct Instance {
///
align(1) mat3 matrix = mat3.identity;
///
align(1) float weight = 1;
///
align(1) float smooth = 0.001;
///
align(1) vec4 color = vec4(0, 0, 0, 0);
}
///
enum ShaderHeader = "#version 330 core
#extension GL_ARB_explicit_uniform_location : enable";
///
enum VertexShaderSrc = ShaderHeader ~ q{
layout(location = 0) in vec2 vert;
layout(location = 1) in vec3 m1;
layout(location = 2) in vec3 m2;
layout(location = 3) in vec3 m3;
layout(location = 4) in float weight;
layout(location = 5) in float smoooth; // expected wrong spell
layout(location = 6) in vec4 color;
out vec2 uv_;
out float weight_;
out float smooth_;
out vec4 color_;
void main() {
mat3 m = transpose(mat3(m1, m2, m3));
vec2 pos = (m * vec3(vert, 1)).xy;
uv_ = vert;
weight_ = weight;
smooth_ = smoooth;
color_ = color;
gl_Position = vec4(pos, 0, 1);
}
};
///
enum FragmentShaderSrc = ShaderHeader ~ q{
in vec2 uv_;
in float weight_;
in float smooth_;
in vec4 color_;
out vec4 pixel_;
float shape() {
$BODY
}
void main() {
pixel_ = color_;
pixel_.a *= shape();
}
}.replace("$BODY", ShaderSrc);
///
this() {
ProgramLinker linker;
linker.vertex = VertexShader.Compile(VertexShaderSrc);
linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
program_ = linker.Link();
program_.Validate();
}
///
void SetupVertexArray(ref VertexArrayRef vao,
ref ArrayBufferRef verts, ref ArrayBufferRef instances) {
with (VertexArrayAttacher()) {
// verts
type = GL_FLOAT;
dimension = 2;
Attach(vao, verts);
++index;
type = GL_FLOAT;
divisor = 1;
stride = Instance.sizeof;
offset = 0;
// matrix
dimension = 3;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
// weight
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// smooth
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// color
dimension = 4;
Attach(vao, instances);
offset += float.sizeof*4;
++index;
}
}
///
void Use() {
program_.Use();
}
private:
ProgramRef program_;
}

View File

@ -8,6 +8,7 @@ import gl4d;
import sjplayer.ElementDrawer, import sjplayer.ElementDrawer,
sjplayer.ElementInterface, sjplayer.ElementInterface,
sjplayer.ShapeElementProgram,
sjplayer.util.linalg; sjplayer.util.linalg;
/// ///
@ -81,123 +82,10 @@ alias SquareElementDrawer = ElementDrawer!(
[vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]); [vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
/// ///
class SquareElementProgram { alias SquareElementProgram = ShapeElementProgram!(q{
public:
///
enum ShaderHeader = "#version 330 core
#extension GL_ARB_explicit_uniform_location : enable";
///
enum VertexShaderSrc = ShaderHeader ~ q{
layout(location = 0) in vec2 vert;
layout(location = 1) in vec3 m1;
layout(location = 2) in vec3 m2;
layout(location = 3) in vec3 m3;
layout(location = 4) in float weight;
layout(location = 5) in float smoooth; // expected wrong spell
layout(location = 6) in vec4 color;
out vec2 uv_;
out float weight_;
out float smooth_;
out vec4 color_;
void main() {
mat3 m = transpose(mat3(m1, m2, m3));
vec2 pos = (m * vec3(vert, 1)).xy;
uv_ = vert;
weight_ = weight;
smooth_ = smoooth;
color_ = color;
gl_Position = vec4(pos, 0, 1);
}
};
///
enum FragmentShaderSrc = ShaderHeader ~ q{
in vec2 uv_;
in float weight_;
in float smooth_;
in vec4 color_;
out vec4 pixel_;
float square() {
float w = 1-weight_; float w = 1-weight_;
float s = smooth_; float s = smooth_;
return clamp( return clamp(
smoothstep(w-s, w, abs(uv_.x)) + smoothstep(w-s, w, abs(uv_.x)) +
smoothstep(w-s, w, abs(uv_.y)), 0, 1); smoothstep(w-s, w, abs(uv_.y)), 0, 1);
} });
void main() {
pixel_ = color_;
pixel_.a *= square();
}
};
///
this() {
ProgramLinker linker;
linker.vertex = VertexShader.Compile(VertexShaderSrc);
linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
program_ = linker.Link();
program_.Validate();
}
///
void SetupVertexArray(ref VertexArrayRef vao,
ref ArrayBufferRef verts, ref ArrayBufferRef instances) {
with (VertexArrayAttacher()) {
// verts
type = GL_FLOAT;
dimension = 2;
Attach(vao, verts);
++index;
type = GL_FLOAT;
divisor = 1;
stride = SquareElement.Instance.sizeof;
offset = 0;
// matrix
dimension = 3;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
Attach(vao, instances);
offset += float.sizeof*3;
++index;
// weight
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// smooth
dimension = 1;
Attach(vao, instances);
offset += float.sizeof*1;
++index;
// color
dimension = 4;
Attach(vao, instances);
offset += float.sizeof*4;
++index;
}
}
///
void Use() {
program_.Use();
}
private:
ProgramRef program_;
}