[add] Added a background controller.
This commit is contained in:
parent
58621115e0
commit
f8c1793dfc
112
sjplayer/src/sjplayer/Background.d
Normal file
112
sjplayer/src/sjplayer/Background.d
Normal 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_;
|
||||||
|
}
|
65
sjplayer/src/sjplayer/BackgroundScheduledController.d
Normal file
65
sjplayer/src/sjplayer/BackgroundScheduledController.d
Normal 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_;
|
||||||
|
}
|
@ -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_;
|
||||||
|
@ -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 =
|
||||||
|
@ -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() {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user