[update] Improved memory efficiency of ShapeElementProgram.
This commit is contained in:
parent
f5500b0b98
commit
3d992ee73b
@ -9,13 +9,14 @@ import gl4d;
|
|||||||
|
|
||||||
import sjplayer.AbstractShapeElement,
|
import sjplayer.AbstractShapeElement,
|
||||||
sjplayer.ElementDrawerInterface,
|
sjplayer.ElementDrawerInterface,
|
||||||
|
sjplayer.ScriptRuntimeException,
|
||||||
sjplayer.ShapeElementProgram;
|
sjplayer.ShapeElementProgram;
|
||||||
|
|
||||||
///
|
///
|
||||||
class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
enum MaxInstanceCount = 512;
|
enum DefaultInstanceCount = 128;
|
||||||
|
|
||||||
///
|
///
|
||||||
this(Program program, in AbstractShapeElement[] shapes)
|
this(Program program, in AbstractShapeElement[] shapes)
|
||||||
@ -42,22 +43,18 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instances_.Bind();
|
instances_.Bind();
|
||||||
with (ArrayBufferAllocator()) {
|
AllocateInstanceBufferIfNeeded(DefaultInstanceCount);
|
||||||
size = ShapeElementProgramInstance.sizeof * MaxInstanceCount;
|
|
||||||
usage = GL_DYNAMIC_DRAW;
|
|
||||||
Allocate(instances_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void Draw() {
|
override void Draw() {
|
||||||
size_t alive_count;
|
const alive_count = shapes_.filter!"a.alive".count!"true";
|
||||||
|
|
||||||
instances_.Bind();
|
instances_.Bind();
|
||||||
|
AllocateInstanceBufferIfNeeded(alive_count);
|
||||||
{
|
{
|
||||||
auto ptr = instances_.MapToWrite!ShapeElementProgramInstance();
|
auto data = instances_.MapToWrite!ShapeElementProgramInstance();
|
||||||
|
auto ptr = data.entity;
|
||||||
foreach (const shape; shapes_.filter!"a.alive") {
|
foreach (const shape; shapes_.filter!"a.alive") {
|
||||||
enforce(alive_count <= MaxInstanceCount);
|
*ptr++ = shape.instance;
|
||||||
ptr[alive_count++] = shape.instance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +67,17 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void AllocateInstanceBufferIfNeeded(size_t count) {
|
||||||
|
if (instances_count_ >= count) return;
|
||||||
|
|
||||||
|
with (ArrayBufferAllocator()) {
|
||||||
|
size = ShapeElementProgramInstance.sizeof * count;
|
||||||
|
usage = GL_DYNAMIC_DRAW;
|
||||||
|
Allocate(instances_);
|
||||||
|
}
|
||||||
|
instances_count_ = count;
|
||||||
|
}
|
||||||
|
|
||||||
Program program_;
|
Program program_;
|
||||||
|
|
||||||
const AbstractShapeElement[] shapes_;
|
const AbstractShapeElement[] shapes_;
|
||||||
@ -77,4 +85,6 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
|
|||||||
ArrayBufferRef verts_;
|
ArrayBufferRef verts_;
|
||||||
ArrayBufferRef instances_;
|
ArrayBufferRef instances_;
|
||||||
VertexArrayRef vao_;
|
VertexArrayRef vao_;
|
||||||
|
|
||||||
|
size_t instances_count_;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user