[add] Added CubeProgram.
This commit is contained in:
parent
361678a94f
commit
58e88e9eb4
@ -23,7 +23,7 @@ class AbstractGame {
|
|||||||
}
|
}
|
||||||
///
|
///
|
||||||
void Draw() {
|
void Draw() {
|
||||||
gl.Clear(GL_COLOR_BUFFER_BIT);
|
gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
scene_.Draw();
|
scene_.Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
194
src/sj/CubeProgram.d
Normal file
194
src/sj/CubeProgram.d
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/// License: MIT
|
||||||
|
module sj.CubeProgram;
|
||||||
|
|
||||||
|
import std.conv,
|
||||||
|
std.range.primitives;
|
||||||
|
|
||||||
|
import gl4d;
|
||||||
|
|
||||||
|
///
|
||||||
|
class CubeProgram {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
alias Instance = mat4;
|
||||||
|
|
||||||
|
///
|
||||||
|
enum ShaderHeader = "#version 330 core
|
||||||
|
#extension GL_ARB_explicit_uniform_location : enable";
|
||||||
|
|
||||||
|
///
|
||||||
|
enum VertexShaderSrc = ShaderHeader ~ q{
|
||||||
|
layout(location = 0) in vec3 vert;
|
||||||
|
layout(location = 1) in vec3 normal;
|
||||||
|
|
||||||
|
layout(location = 2) in vec4 m1;
|
||||||
|
layout(location = 3) in vec4 m2;
|
||||||
|
layout(location = 4) in vec4 m3;
|
||||||
|
layout(location = 5) in vec4 m4;
|
||||||
|
|
||||||
|
out vec3 normal_;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 m = transpose(mat4(m1, m2, m3, m4));
|
||||||
|
|
||||||
|
normal_ = (m * vec4(normal, 1)).xyz;
|
||||||
|
gl_Position = m * vec4(vert, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
///
|
||||||
|
enum FragmentShaderSrc = ShaderHeader ~ q{
|
||||||
|
layout(location = 0) uniform vec3 light_color;
|
||||||
|
layout(location = 1) uniform vec3 light_direction;
|
||||||
|
layout(location = 2) uniform vec3 ambient_color;
|
||||||
|
|
||||||
|
in vec3 normal_;
|
||||||
|
|
||||||
|
out vec4 pixel_;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float light = dot(normalize(light_direction), normalize(normal_));
|
||||||
|
vec3 color = clamp(light_color * light + ambient_color, 0, 1);
|
||||||
|
|
||||||
|
pixel_ = vec4(color, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
enum MaxInstanceCount = 10;
|
||||||
|
|
||||||
|
///
|
||||||
|
this() {
|
||||||
|
ProgramLinker linker;
|
||||||
|
linker.vertex = VertexShader.Compile(VertexShaderSrc);
|
||||||
|
linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
|
||||||
|
program_ = linker.Link();
|
||||||
|
program_.Validate();
|
||||||
|
|
||||||
|
vao_ = VertexArray.Create();
|
||||||
|
verts_ = ArrayBuffer.Create();
|
||||||
|
instances_ = ArrayBuffer.Create();
|
||||||
|
|
||||||
|
vao_.Bind();
|
||||||
|
VertexArrayAttacher attacher;
|
||||||
|
with (attacher) {
|
||||||
|
index = 0;
|
||||||
|
type = GL_FLOAT;
|
||||||
|
offset = vec3.sizeof * 0;
|
||||||
|
stride = vec3.sizeof * 2;
|
||||||
|
dimension = 3;
|
||||||
|
Attach(vao_, verts_);
|
||||||
|
|
||||||
|
index = 1;
|
||||||
|
type = GL_FLOAT;
|
||||||
|
offset = vec3.sizeof * 1;
|
||||||
|
stride = vec3.sizeof * 2;
|
||||||
|
dimension = 3;
|
||||||
|
Attach(vao_, verts_);
|
||||||
|
|
||||||
|
index = 2;
|
||||||
|
type = GL_FLOAT;
|
||||||
|
offset = vec4.sizeof * 0;
|
||||||
|
stride = vec4.sizeof * 4;
|
||||||
|
dimension = 4;
|
||||||
|
divisor = 1;
|
||||||
|
Attach(vao_, instances_);
|
||||||
|
index = 3;
|
||||||
|
offset += vec4.sizeof;
|
||||||
|
Attach(vao_, instances_);
|
||||||
|
index = 4;
|
||||||
|
offset += vec4.sizeof;
|
||||||
|
Attach(vao_, instances_);
|
||||||
|
index = 5;
|
||||||
|
offset += vec4.sizeof;
|
||||||
|
Attach(vao_, instances_);
|
||||||
|
}
|
||||||
|
|
||||||
|
verts_.Bind();
|
||||||
|
ArrayBufferAllocator verts_allocator;
|
||||||
|
with (verts_allocator) {
|
||||||
|
enum v = [
|
||||||
|
// left
|
||||||
|
vec3(-1, 1, -1), vec3(-1, 1, 1), vec3(-1, -1, 1),
|
||||||
|
vec3(-1, 1, -1), vec3(-1, -1, -1), vec3(-1, -1, 1),
|
||||||
|
|
||||||
|
// right
|
||||||
|
vec3(1, 1, -1), vec3(1, 1, 1), vec3(1, -1, 1),
|
||||||
|
vec3(1, 1, -1), vec3(1, -1, -1), vec3(1, -1, 1),
|
||||||
|
|
||||||
|
// top
|
||||||
|
vec3(-1, 1, -1), vec3(-1, 1, 1), vec3(1, 1, 1),
|
||||||
|
vec3(-1, 1, -1), vec3( 1, 1, -1), vec3(1, 1, 1),
|
||||||
|
|
||||||
|
// bottom
|
||||||
|
vec3(-1, -1, -1), vec3(-1, -1, 1), vec3(1, -1, 1),
|
||||||
|
vec3(-1, -1, -1), vec3( 1, -1, -1), vec3(1, -1, 1),
|
||||||
|
|
||||||
|
// front
|
||||||
|
vec3(-1, 1, -1), vec3( 1, 1, -1), vec3(1, -1, -1),
|
||||||
|
vec3(-1, 1, -1), vec3(-1, -1, -1), vec3(1, -1, -1),
|
||||||
|
|
||||||
|
// back
|
||||||
|
vec3(-1, 1, 1), vec3( 1, 1, 1), vec3(1, -1, 1),
|
||||||
|
vec3(-1, 1, 1), vec3(-1, -1, 1), vec3(1, -1, 1),
|
||||||
|
];
|
||||||
|
enum n = [
|
||||||
|
vec3(-1, 0, 0), // left
|
||||||
|
vec3( 1, 0, 0), // right
|
||||||
|
vec3( 0, 1, 0), // top
|
||||||
|
vec3( 0, -1, 0), // bottom
|
||||||
|
vec3( 0, 0, -1), // front
|
||||||
|
vec3( 0, 0, 1), // back
|
||||||
|
];
|
||||||
|
enum d = {
|
||||||
|
vec3[] d;
|
||||||
|
foreach (i, p; v) d ~= [p, n[i/6]];
|
||||||
|
return d;
|
||||||
|
}();
|
||||||
|
|
||||||
|
const d_mem = d;
|
||||||
|
data = d_mem.ptr;
|
||||||
|
size = d_mem[0].sizeof * d_mem.length;
|
||||||
|
usage = GL_STATIC_DRAW;
|
||||||
|
Allocate(verts_);
|
||||||
|
}
|
||||||
|
|
||||||
|
instances_.Bind();
|
||||||
|
ArrayBufferAllocator instances_allocator;
|
||||||
|
with (instances_allocator) {
|
||||||
|
data = null;
|
||||||
|
size = MaxInstanceCount * Instance.sizeof;
|
||||||
|
usage = GL_DYNAMIC_DRAW;
|
||||||
|
Allocate(instances_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void Draw(R)(R cubes, vec3 lcolor, vec3 light, vec3 acolor)
|
||||||
|
if (isInputRange!R && is(ElementType!R == Instance)) {
|
||||||
|
size_t length;
|
||||||
|
{
|
||||||
|
auto ptr = instances_.MapToWrite!Instance();
|
||||||
|
foreach (const ref c; cubes) {
|
||||||
|
assert(length < MaxInstanceCount);
|
||||||
|
ptr[length++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
program_.Use();
|
||||||
|
program_.uniform!0 = lcolor;
|
||||||
|
program_.uniform!1 = light;
|
||||||
|
program_.uniform!2 = acolor;
|
||||||
|
|
||||||
|
vao_.Bind();
|
||||||
|
gl.DrawArraysInstanced(GL_TRIANGLES, 0, 6*6, length.to!int);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProgramRef program_;
|
||||||
|
|
||||||
|
VertexArrayRef vao_;
|
||||||
|
|
||||||
|
ArrayBufferRef verts_;
|
||||||
|
|
||||||
|
ArrayBufferRef instances_;
|
||||||
|
}
|
@ -1,21 +1,38 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sj.LobbyWorld;
|
module sj.LobbyWorld;
|
||||||
|
|
||||||
|
import std.algorithm;
|
||||||
|
|
||||||
|
import gl4d;
|
||||||
|
|
||||||
import sjplayer.Background;
|
import sjplayer.Background;
|
||||||
|
|
||||||
import sj.ProgramSet;
|
import sj.CubeProgram,
|
||||||
|
sj.ProgramSet;
|
||||||
|
|
||||||
///
|
///
|
||||||
class LobbyWorld {
|
class LobbyWorld {
|
||||||
public:
|
public:
|
||||||
|
///
|
||||||
|
enum Perspective = mat4.perspective(-0.5, 0.5, -0.5, 0.5, 0.1, 100);
|
||||||
|
|
||||||
///
|
///
|
||||||
this(ProgramSet programs) {
|
this(ProgramSet programs) {
|
||||||
background_ = new Background(programs.forPlayers.Get!BackgroundProgram);
|
background_ = new Background(programs.Get!BackgroundProgram);
|
||||||
|
cube_ = programs.Get!CubeProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void Draw() {
|
void Draw() {
|
||||||
|
gl.Disable(GL_DEPTH_TEST);
|
||||||
|
gl.DepthMask(false);
|
||||||
background_.Draw();
|
background_.Draw();
|
||||||
|
|
||||||
|
gl.Enable(GL_DEPTH_TEST);
|
||||||
|
gl.DepthMask(true);
|
||||||
|
cube_.Draw(
|
||||||
|
cubes.map!(x => Perspective * view * x),
|
||||||
|
light_color, light_direction, ambient_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -23,6 +40,19 @@ class LobbyWorld {
|
|||||||
return background_;
|
return background_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
mat4[] cubes;
|
||||||
|
///
|
||||||
|
mat4 view = mat4.look_at(vec3(0, 0, -1), vec3(0, 0, 0), vec3(0, 1, 0));
|
||||||
|
///
|
||||||
|
vec3 light_color = vec3(1, 1, 1, 1);
|
||||||
|
///
|
||||||
|
vec3 light_direction = vec3(0, 1, 0);
|
||||||
|
///
|
||||||
|
vec3 ambient_color = vec3(0.1, 0.1, 0.1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Background background_;
|
Background background_;
|
||||||
|
|
||||||
|
CubeProgram cube_;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,46 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sj.ProgramSet;
|
module sj.ProgramSet;
|
||||||
|
|
||||||
|
import std.meta,
|
||||||
|
std.typecons;
|
||||||
|
|
||||||
static import sjplayer = sjplayer.ProgramSet;
|
static import sjplayer = sjplayer.ProgramSet;
|
||||||
|
|
||||||
|
import sj.CubeProgram;
|
||||||
|
|
||||||
///
|
///
|
||||||
class ProgramSet {
|
class ProgramSet {
|
||||||
public:
|
public:
|
||||||
|
alias Programs = Tuple!(
|
||||||
|
CubeProgram,
|
||||||
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
this() {
|
this() {
|
||||||
for_players_ = new sjplayer.ProgramSet;
|
for_player_ = new sjplayer.ProgramSet;
|
||||||
|
foreach (ref p; programs_) {
|
||||||
|
p = new typeof(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~this() {
|
~this() {
|
||||||
for_players_.destroy();
|
for_player_.destroy();
|
||||||
|
foreach (p; programs_) {
|
||||||
|
p.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@property sjplayer.ProgramSet forPlayers() {
|
T Get(T)() {
|
||||||
return for_players_;
|
enum index = staticIndexOf!(T, Programs.Types);
|
||||||
|
static if (index >= 0) {
|
||||||
|
return programs_[index];
|
||||||
|
} else {
|
||||||
|
return for_player_.Get!T;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sjplayer.ProgramSet for_players_;
|
sjplayer.ProgramSet for_player_;
|
||||||
|
|
||||||
|
Programs programs_;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user