[add] Added ElementDrawer.

This commit is contained in:
falsycat 2019-10-10 00:00:00 +00:00
parent 79bfed8d19
commit 4cd1f578d2
2 changed files with 85 additions and 67 deletions

View File

@ -2,13 +2,11 @@
module sjplayer.CircleElement; module sjplayer.CircleElement;
import std.algorithm, import std.algorithm,
std.conv, std.math;
std.math,
std.exception;
import gl4d; import gl4d;
import sjplayer.ElementDrawerInterface, import sjplayer.ElementDrawer,
sjplayer.ElementInterface; sjplayer.ElementInterface;
/// ///
@ -80,69 +78,10 @@ class CircleElement : ElementInterface {
} }
/// ///
class CircleElementDrawer : ElementDrawerInterface { alias CircleElementDrawer = ElementDrawer!(
public: CircleElementProgram,
/// CircleElement,
this(CircleElementProgram program, in CircleElement[] elements) [vec2(-1, 1), vec2(1, 1), vec2(1, -1), vec2(-1, -1)]);
in (program)
in (elements.length > 0) {
program_ = program;
elements_ = elements;
vao_ = VertexArray.Create();
verts_ = ArrayBuffer.Create();
instances_ = ArrayBuffer.Create();
vao_.Bind();
program_.SetupVertexArray(vao_, verts_, instances_);
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_);
}
instances_.Bind();
ArrayBufferAllocator instance_allocator;
with (instance_allocator) {
size = CircleElement.Instance.sizeof * elements.length;
usage = GL_DYNAMIC_DRAW;
Allocate(instances_);
}
}
override void Draw() {
size_t alive_count;
instances_.Bind();
ArrayBufferOverwriter instance_writer;
foreach (const element; elements_.filter!"a.alive") with (instance_writer) {
data = &element.instance;
offset = alive_count++ * CircleElement.Instance.sizeof;
size = CircleElement.Instance.sizeof;
Overwrite(instances_);
}
program_.Use();
vao_.Bind();
if (alive_count == 0) return;
gl.DrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, alive_count.to!int);
}
private:
CircleElementProgram program_;
const CircleElement[] elements_;
ArrayBufferRef verts_;
ArrayBufferRef instances_;
VertexArrayRef vao_;
}
/// ///
class CircleElementProgram { class CircleElementProgram {

View File

@ -0,0 +1,79 @@
/// License: MIT
module sjplayer.ElementDrawer;
import std.algorithm,
std.conv;
import gl4d;
import sjplayer.ElementDrawerInterface;
///
class ElementDrawer(Program, Element, vec2[] vertices) :
ElementDrawerInterface {
public:
///
alias Instance = typeof(Element.instance);
///
this(Program program, in Element[] elements)
in (program)
in (elements.length > 0) {
program_ = program;
elements_ = elements;
vao_ = VertexArray.Create();
verts_ = ArrayBuffer.Create();
instances_ = ArrayBuffer.Create();
vao_.Bind();
program_.SetupVertexArray(vao_, verts_, instances_);
verts_.Bind();
ArrayBufferAllocator verts_allocator;
with (verts_allocator) {
const v = vertices; // place to memory
data = v.ptr;
size = typeof(v[0]).sizeof * v.length;
usage = GL_STATIC_DRAW;
Allocate(verts_);
}
instances_.Bind();
ArrayBufferAllocator instance_allocator;
with (instance_allocator) {
size = Instance.sizeof * elements.length;
usage = GL_DYNAMIC_DRAW;
Allocate(instances_);
}
}
override void Draw() {
size_t alive_count;
instances_.Bind();
{
auto ptr = instances_.MapToWrite!Instance();
foreach (const element; elements_.filter!"a.alive") {
ptr[alive_count++] = element.instance;
}
}
program_.Use();
vao_.Bind();
if (alive_count == 0) return;
gl.DrawArraysInstanced(
GL_TRIANGLE_FAN, 0, vertices.length.to!int, alive_count.to!int);
}
private:
Program program_;
const Element[] elements_;
ArrayBufferRef verts_;
ArrayBufferRef instances_;
VertexArrayRef vao_;
}