Skip to content

Commit

Permalink
Use instancing to further enhnace rendering efficiency
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoplitein committed Oct 18, 2015
1 parent a2442a2 commit ef8f75e
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 33 deletions.
8 changes: 4 additions & 4 deletions dub.json
Expand Up @@ -4,9 +4,9 @@
"copyright": "Copyright © 2015, Steven",
"authors": ["Steven"],
"dependencies": {
"gfm:logger": "~>3.0.5",
"gfm:sdl2": "~>3.0.5",
"gfm:math": "~>3.0.5",
"gfm:opengl": "~>3.0.5",
"gfm:logger": "~>3.0.6",
"gfm:sdl2": "~>3.0.6",
"gfm:math": "~>3.0.6",
"gfm:opengl": "~>3.0.6",
},
}
10 changes: 5 additions & 5 deletions res/shader.fs
Expand Up @@ -2,26 +2,26 @@
#define TEXTURE_SIZE 32u

in vec2 fragmentTextureCoordinate;
flat in uint fragmentTextureIndex;
in vec3 fragmentColorMask;

out vec4 outColor;

uniform uint atlasSizePixels; //size of the atlas in pixels
uniform uint atlasSizeTiles; //size of the atlas in TEXTURE_SIZE tiles
uniform float atlasTileSizeFloating; //size of a tile on the atlas in floating coords
uniform uint index; //index into the atlas for the tile to use
uniform sampler2D activeTexture;
uniform vec3 colorMask;

void main()
{
uvec2 tileCoords = uvec2(
index % atlasSizeTiles,
index / atlasSizeTiles
fragmentTextureIndex % atlasSizeTiles,
fragmentTextureIndex / atlasSizeTiles
);
uvec2 pixelCoords = tileCoords * TEXTURE_SIZE;
vec2 floatingCoords = pixelCoords / float(atlasSizePixels);
vec2 flippedCoords = vec2(fragmentTextureCoordinate.x, 1 -fragmentTextureCoordinate.y);
vec2 finalCoords = floatingCoords + flippedCoords * atlasTileSizeFloating;

outColor = vec4(colorMask, 1.0) * texture(activeTexture, finalCoords);
outColor = vec4(fragmentColorMask, 1.0) * texture(activeTexture, finalCoords);
}
17 changes: 16 additions & 1 deletion res/shader.vs
Expand Up @@ -2,16 +2,31 @@

in vec2 coordinate;
in vec2 textureCoordinate;
in vec4 maskAndIndex; //color mask and texture index in single vector to work around gfm limitations
//model matrix unpacked as four vec4s, again working around gfm limitations
in vec4 modelColumn1;
in vec4 modelColumn2;
in vec4 modelColumn3;
in vec4 modelColumn4;

out vec2 fragmentTextureCoordinate;
flat out uint fragmentTextureIndex;
out vec3 fragmentColorMask;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main()
{
mat4 model = mat4(
modelColumn1,
modelColumn2,
modelColumn3,
modelColumn4
);
fragmentTextureCoordinate = textureCoordinate;
fragmentTextureIndex = uint(maskAndIndex.w);
fragmentColorMask = maskAndIndex.rgb;
vec4 coordinate4 = vec4(coordinate, 0.0, 1.0);
gl_Position = projection * view * model * coordinate4;
}
75 changes: 58 additions & 17 deletions src/pacman/gl/renderer.d
@@ -1,5 +1,6 @@
module pacman.gl.renderer;

import std.array;
import std.experimental.logger;
import std.file;
import std.string;
Expand All @@ -11,20 +12,34 @@ import pacman.gl.texture;
import pacman.globals;
import pacman;

struct Vertex
private struct Vertex
{
vec2f coordinate;
vec2f textureCoordinate;
}

private struct Instance
{
vec4f maskAndIndex; //color mask and texture index in single vector to work around gfm limitations
//model matrix unpacked as four vec4s, again working around gfm limitations
vec4f modelColumn1;
vec4f modelColumn2;
vec4f modelColumn3;
vec4f modelColumn4;
}

class Renderer
{
private GLProgram _program;
private GLBuffer buffer;
private VertexSpecification!Vertex specification;
private GLBuffer shapeBuffer;
private GLBuffer instanceBuffer;
private VertexSpecification!Vertex shapeSpecification;
private VertexSpecification!Instance instanceSpecification;
private GLsizei shapeVertexCount;
private bool firstUpdate = true;
private mat4 view;
private mat4 projection;
private Appender!(Instance[]) instances;

this()
{
Expand Down Expand Up @@ -79,11 +94,18 @@ class Renderer
vec2f(uvMin, uvMin)
),
];
buffer = new GLBuffer(opengl, GL_ARRAY_BUFFER, GL_STATIC_DRAW, shape.dup);
specification = new VertexSpecification!Vertex(_program);
shapeBuffer = new GLBuffer(opengl, GL_ARRAY_BUFFER, GL_STATIC_DRAW, shape.dup);
shapeSpecification = new VertexSpecification!Vertex(_program);
shapeVertexCount = cast(GLsizei)(shapeBuffer.size / shapeSpecification.vertexSize);

shapeBuffer.bind;
shapeSpecification.use;

instanceBuffer = new GLBuffer(opengl, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, null);
instanceSpecification = new VertexSpecification!Instance(_program);

buffer.bind;
specification.use;
instanceBuffer.bind;
instanceSpecification.use(1);
}

projection = mat4.orthographic(
Expand All @@ -92,6 +114,7 @@ class Renderer
0.0, 5.0,
);

_program.uniform("activeTexture").set(0);
_program.uniform("projection").set(projection);
_program.uniform("view").set(view);
}
Expand All @@ -104,7 +127,8 @@ class Renderer
void close()
{
_program.destroy;
buffer.destroy;
shapeBuffer.destroy;
instanceBuffer.destroy;
}

void update()
Expand Down Expand Up @@ -133,17 +157,34 @@ class Renderer
void copy(TextureData data, int x, int y, real rotation = 0, vec3f color = vec3f(1, 1, 1))
{
enum halfSize = TEXTURE_SIZE / 2f;
mat4 model =
mat4.translation(vec3f(cast(float)x + halfSize, cast(float)y + halfSize, 0)) *
mat4.rotation(rotation.radians, vec3f(0, 0, 1))
;

program.uniform("model").set(
mat4.translation(vec3f(cast(float)x, cast(float)y, 0)) *
mat4.translation(vec3f(halfSize, halfSize, 0)) *
mat4.rotation(rotation.radians, vec3f(0, 0, 1)) *
mat4.translation(vec3f(-halfSize, -halfSize, 0)) *
mat4.scaling(vec3f(TEXTURE_SIZE, TEXTURE_SIZE, 0))
model.translate(vec3f(-halfSize, -halfSize, 0));
model.scale(vec3f(TEXTURE_SIZE, TEXTURE_SIZE, 0));
instances.put(
Instance(
vec4f(color, cast(float)data.index),
model.column(0),
model.column(1),
model.column(2),
model.column(3),
)
);
}

void flush()
{
instanceBuffer.setData(instances.data);
glDrawArraysInstanced(
GL_TRIANGLES,
0,
shapeVertexCount,
instances.data.length,
);
program.uniform("colorMask").set(color);
program.uniform("index").set(data.index);
glDrawArrays(GL_TRIANGLES, 0, cast(int)(buffer.size / specification.vertexSize));
instances.clear;
}
}

Expand Down
7 changes: 1 addition & 6 deletions src/pacman/main.d
Expand Up @@ -78,11 +78,6 @@ void main()

stitch_textures;
regenerate_level;
renderer.program.uniform("model").set(
mat4.translation(vec3f(15, 15, 0)) *
mat4.scaling(vec3f(200, 200, 1))
);
renderer.program.uniform("activeTexture").set(0);

while(true)
{
Expand Down Expand Up @@ -150,7 +145,7 @@ void main()

player.update;
player.render;
//renderer.draw;
renderer.flush;
window.swapBuffers;
}

Expand Down
1 change: 1 addition & 0 deletions src/pacman/package.d
Expand Up @@ -8,3 +8,4 @@ alias vec3i = gfm.math.vec3!int;
alias mat4 = gfm.math.mat4!float;
alias vec2f = gfm.math.vec2!float;
alias vec3f = gfm.math.vec3!float;
alias vec4f = gfm.math.vec4!float;

0 comments on commit ef8f75e

Please sign in to comment.