[add] Added a background controller.

This commit is contained in:
falsycat 2019-10-07 00:00:00 +00:00
parent 58621115e0
commit f8c1793dfc
6 changed files with 203 additions and 6 deletions

View File

@ -0,0 +1,112 @@
/// License: MIT
module sjplayer.Background;
import gl4d;
///
class Background {
public:
///
this(BackgroundProgram program) {
program_ = program;
}
///
void Initialize() {
inner_color = vec4(0, 0, 0, 0);
outer_color = vec4(0, 0, 0, 0);
}
///
void Draw() {
program_.Draw(inner_color, outer_color);
}
///
vec4 inner_color;
///
vec4 outer_color;
private:
BackgroundProgram program_;
}
///
class BackgroundProgram {
public:
///
enum ShaderHeader = "#version 330 core
#extension GL_ARB_explicit_uniform_location : enable";
///
enum VertexShaderSrc = ShaderHeader ~ q{
layout(location = 0) in vec2 vert;
out vec2 uv_;
void main() {
uv_ = vert;
gl_Position = vec4(vert, 0, 1);
}
};
///
enum FragmentShaderSrc = ShaderHeader ~ q{
layout(location = 0) uniform vec4 inner_color;
layout(location = 1) uniform vec4 outer_color;
in vec2 uv_;
out vec4 pixel_;
void main() {
pixel_ = (outer_color - inner_color)*length(uv_)/sqrt(2) + outer_color;
}
};
///
this() {
ProgramLinker linker;
linker.vertex = VertexShader.Compile(VertexShaderSrc);
linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
program_ = linker.Link();
program_.Validate();
vao_ = VertexArray.Create();
verts_ = ArrayBuffer.Create();
vao_.Bind();
VertexArrayAttacher attacher;
with (attacher) {
index = 0;
type = GL_FLOAT;
dimension = 2;
Attach(vao_, verts_);
}
verts_.Bind();
ArrayBufferAllocator verts_allocator;
with (verts_allocator) {
const v = [vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1),];
data = v.ptr;
size = typeof(v[0]).sizeof * v.length;
usage = GL_STATIC_DRAW;
Allocate(verts_);
}
}
///
void Draw(vec4 inner, vec4 outer) {
program_.Use();
program_.uniform!0 = inner;
program_.uniform!1 = outer;
vao_.Bind();
gl.DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
private:
ProgramRef program_;
ArrayBufferRef verts_;
VertexArrayRef vao_;
}

View File

@ -0,0 +1,65 @@
/// License: MIT
module sjplayer.BackgroundScheduledController;
import std.algorithm,
std.array,
std.exception,
std.range.primitives;
import sjscript;
import sjplayer.Background,
sjplayer.ContextBuilderInterface,
sjplayer.ElementScheduledController,
sjplayer.VarStoreInterface,
sjplayer.util.Period;
///
alias BackgroundScheduledController = ElementScheduledController!(
Background,
[
"inner_r": "inner_color.r",
"inner_g": "inner_color.g",
"inner_b": "inner_color.b",
"inner_a": "inner_color.a",
"outer_r": "outer_color.r",
"outer_g": "outer_color.g",
"outer_b": "outer_color.b",
"outer_a": "outer_color.a",
]
);
///
struct BackgroundScheduledControllerFactory {
public:
@disable this();
///
this(
in VarStoreInterface varstore,
Background background) {
varstore_ = varstore;
background_ = background;
}
///
void Create(R)(R params, ContextBuilderInterface builder)
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
auto params_array = params.array;
params_array.sort!"a.period.start < b.period.start";
auto before = Period(-1, 0);
foreach (param; params_array) {
(!param.period.IsPeriodIntersectedToPeriod(before)).enforce();
}
auto ctrl = new BackgroundScheduledController(
background_, varstore_, params_array);
builder.AddScheduledController(ctrl);
}
private:
const VarStoreInterface varstore_;
Background background_;
}

View File

@ -7,7 +7,8 @@ import std.algorithm,
import sjscript; import sjscript;
import sjplayer.ContextBuilderInterface, import sjplayer.Background,
sjplayer.ContextBuilderInterface,
sjplayer.ElementInterface, sjplayer.ElementInterface,
sjplayer.ProgramSet, sjplayer.ProgramSet,
sjplayer.ScheduledControllerInterface, sjplayer.ScheduledControllerInterface,
@ -21,8 +22,15 @@ class Context {
auto builder = new Builder; auto builder = new Builder;
auto varstore = new BlackHole!VarStoreInterface; auto varstore = new BlackHole!VarStoreInterface;
import sjplayer.CircleElementScheduledController; background_ = new Background(programs.Get!BackgroundProgram);
import sjplayer.BackgroundScheduledController,
sjplayer.CircleElementScheduledController;
auto factories = tuple( auto factories = tuple(
tuple(
"background",
BackgroundScheduledControllerFactory(varstore, background_),
),
tuple( tuple(
"circle", "circle",
CircleElementScheduledControllerFactory(programs, varstore), CircleElementScheduledControllerFactory(programs, varstore),
@ -42,6 +50,8 @@ class Context {
controllers_.each!destroy; controllers_.each!destroy;
drawers_.each!destroy; drawers_.each!destroy;
elements_.each!destroy; elements_.each!destroy;
background_.destroy();
} }
/// ///
@ -49,6 +59,10 @@ class Context {
assert(false); // TODO: assert(false); // TODO:
} }
/// ///
void DrawBackground() {
background_.Draw();
}
///
void DrawElements() { void DrawElements() {
drawers_.each!(x => x.Draw()); drawers_.each!(x => x.Draw());
} }
@ -74,6 +88,8 @@ class Context {
Appender!(ScheduledControllerInterface[]) controllers; Appender!(ScheduledControllerInterface[]) controllers;
} }
Background background_;
ElementInterface[] elements_; ElementInterface[] elements_;
ElementDrawerInterface[] drawers_; ElementDrawerInterface[] drawers_;

View File

@ -17,8 +17,7 @@ import sjplayer.ElementInterface,
/// ///
class ElementScheduledController( class ElementScheduledController(
Element, string[string] ParameterNameMap) : Element, string[string] ParameterNameMap) :
AbstractScheduledControllerWithOperationImpl AbstractScheduledControllerWithOperationImpl {
if (is(Element : ElementInterface)) {
public: public:
/// ///
enum AliveManagementAvailable = enum AliveManagementAvailable =

View File

@ -4,13 +4,17 @@ module sjplayer.ProgramSet;
import std.meta, import std.meta,
std.typecons; std.typecons;
import sjplayer.CircleElement; import sjplayer.Background,
sjplayer.CircleElement;
/// ///
class ProgramSet { class ProgramSet {
public: public:
/// ///
alias Programs = Tuple!(CircleElementProgram); alias Programs = Tuple!(
BackgroundProgram,
CircleElementProgram
);
/// ///
this() { this() {

View File

@ -39,6 +39,7 @@ int main(string[] args) {
context.OperateScheduledControllers(beat); context.OperateScheduledControllers(beat);
gl.Clear(GL_COLOR_BUFFER_BIT); gl.Clear(GL_COLOR_BUFFER_BIT);
context.DrawBackground();
context.DrawElements(); context.DrawElements();
sfWindow_display(win); sfWindow_display(win);
} }