Add gltk
This commit is contained in:
parent
8d44370067
commit
f6cfbcc406
@ -8,6 +8,7 @@ env "app" do |env|
|
|||||||
"libs/bindbc-common/source",
|
"libs/bindbc-common/source",
|
||||||
"libs/bindbc-sdl/source",
|
"libs/bindbc-sdl/source",
|
||||||
"libs/glad",
|
"libs/glad",
|
||||||
|
"libs/gltk",
|
||||||
]
|
]
|
||||||
sources = dirs.reduce([]) do |result, dir|
|
sources = dirs.reduce([]) do |result, dir|
|
||||||
result + glob("#{dir}/**/*.{d,c}")
|
result + glob("#{dir}/**/*.{d,c}")
|
||||||
|
33
libs/gltk/gltk/array.d
Normal file
33
libs/gltk/gltk/array.d
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
module gltk.array;
|
||||||
|
|
||||||
|
import gl;
|
||||||
|
|
||||||
|
class Array
|
||||||
|
{
|
||||||
|
private GLuint m_id;
|
||||||
|
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
m_id = 0u;
|
||||||
|
glGenVertexArrays(1, &m_id);
|
||||||
|
if (m_id == 0u)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to allocate an OpenGL array");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
glDeleteVertexArrays(1, &m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind()
|
||||||
|
{
|
||||||
|
glBindVertexArray(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property GLuint id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
}
|
48
libs/gltk/gltk/buffer.d
Normal file
48
libs/gltk/gltk/buffer.d
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
module gltk.buffer;
|
||||||
|
|
||||||
|
import gl;
|
||||||
|
|
||||||
|
class Buffer
|
||||||
|
{
|
||||||
|
private GLuint m_id;
|
||||||
|
|
||||||
|
private GLenum m_target;
|
||||||
|
|
||||||
|
this(GLenum target)
|
||||||
|
{
|
||||||
|
m_id = 0u;
|
||||||
|
glGenBuffers(1, &m_id);
|
||||||
|
if (m_id == 0u)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to allocate an OpenGL buffer");
|
||||||
|
}
|
||||||
|
m_target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind()
|
||||||
|
{
|
||||||
|
glBindBuffer(m_target, m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property GLuint id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_buffer_data(GLenum usage, const void * ptr, size_t size)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glBufferData(m_target, size, ptr, usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_buffer_data(T)(GLenum usage, T[] arr)
|
||||||
|
{
|
||||||
|
bind();
|
||||||
|
glBufferData(m_target, arr.length * arr[0].sizeof, arr.ptr, usage);
|
||||||
|
}
|
||||||
|
}
|
7
libs/gltk/gltk/package.d
Normal file
7
libs/gltk/gltk/package.d
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module gltk;
|
||||||
|
|
||||||
|
public import gltk.array;
|
||||||
|
public import gltk.buffer;
|
||||||
|
public import gltk.program;
|
||||||
|
public import gltk.shader;
|
||||||
|
public import gltk.texture;
|
182
libs/gltk/gltk/program.d
Normal file
182
libs/gltk/gltk/program.d
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
module gltk.program;
|
||||||
|
|
||||||
|
import gltk.shader;
|
||||||
|
import std.string;
|
||||||
|
import gl;
|
||||||
|
|
||||||
|
class Program(uniforms...)
|
||||||
|
{
|
||||||
|
/* The number of template parameters must be a multiple of 2. */
|
||||||
|
static assert((uniforms.length % 2) == 0);
|
||||||
|
|
||||||
|
private GLuint m_id;
|
||||||
|
|
||||||
|
static foreach (i, v; uniforms)
|
||||||
|
{
|
||||||
|
static if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
mixin("private GLint m_uniform_" ~ v ~ ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this(Args...)(Args args)
|
||||||
|
{
|
||||||
|
m_id = glCreateProgram();
|
||||||
|
if (m_id == 0u)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to allocate an OpenGL program");
|
||||||
|
}
|
||||||
|
static if (args.length > 0u)
|
||||||
|
{
|
||||||
|
build(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
glDeleteProgram(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach_shader(Shader shader) const
|
||||||
|
{
|
||||||
|
glAttachShader(m_id, shader.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind_attrib_location(string name, uint index) const
|
||||||
|
{
|
||||||
|
glBindAttribLocation(m_id, index, name.toStringz());
|
||||||
|
}
|
||||||
|
|
||||||
|
void link()
|
||||||
|
{
|
||||||
|
glLinkProgram(m_id);
|
||||||
|
|
||||||
|
GLint link_status;
|
||||||
|
glGetProgramiv(m_id, GL_LINK_STATUS, &link_status);
|
||||||
|
if (link_status != GL_TRUE)
|
||||||
|
{
|
||||||
|
string message = "Failed to link program";
|
||||||
|
GLint log_length = 0;
|
||||||
|
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
|
if (log_length > 0)
|
||||||
|
{
|
||||||
|
char[] log = new char[log_length];
|
||||||
|
glGetProgramInfoLog(m_id, log_length, &log_length, log.ptr);
|
||||||
|
message ~= "\n";
|
||||||
|
message ~= log;
|
||||||
|
message ~= "\n";
|
||||||
|
}
|
||||||
|
throw new Exception(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static foreach(i, v; uniforms)
|
||||||
|
{
|
||||||
|
static if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
mixin("m_uniform_" ~ v ~ " = glGetUniformLocation(m_id, \"" ~ v ~ "\");");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint get_uniform_location(string uniform_name) const
|
||||||
|
{
|
||||||
|
return glGetUniformLocation(m_id, uniform_name.toStringz());
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_uniform_locations(Args...)(string uniform_name, GLint * uniform_location, Args args) const
|
||||||
|
{
|
||||||
|
*uniform_location = get_uniform_location(uniform_name);
|
||||||
|
static if (args.length > 0u)
|
||||||
|
{
|
||||||
|
get_uniform_locations(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property GLuint id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void use() const
|
||||||
|
{
|
||||||
|
glUseProgram(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string uniform_param_decl_list(string spec)
|
||||||
|
{
|
||||||
|
int count = spec[0] - '0';
|
||||||
|
string type;
|
||||||
|
if (spec[1] == 'i')
|
||||||
|
{
|
||||||
|
type = "GLint";
|
||||||
|
}
|
||||||
|
else if (spec[1..2] == "ui")
|
||||||
|
{
|
||||||
|
type = "GLuint";
|
||||||
|
}
|
||||||
|
else if (spec[1] == 'f')
|
||||||
|
{
|
||||||
|
type = "GLfloat";
|
||||||
|
}
|
||||||
|
assert(type != "");
|
||||||
|
if (spec[$ - 1] == 'v')
|
||||||
|
{
|
||||||
|
return "uint count, const " ~ type ~ " * v";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string[] decls;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
decls ~= type ~ " v" ~ cast(char)('0' + i);
|
||||||
|
}
|
||||||
|
return decls.join(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string uniform_param_list(string spec)
|
||||||
|
{
|
||||||
|
int count = spec[0] - '0';
|
||||||
|
if (spec[$ - 1] == 'v')
|
||||||
|
{
|
||||||
|
return "count, v";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string[] vees;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
vees ~= "v" ~ cast(char)('0' + i);
|
||||||
|
}
|
||||||
|
return vees.join(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static foreach (i, v; uniforms)
|
||||||
|
{
|
||||||
|
static if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
mixin("void set_" ~ v ~ "(" ~ uniform_param_decl_list(uniforms[i + 1]) ~ ")" ~
|
||||||
|
"{" ~
|
||||||
|
" glUniform" ~ uniforms[i + 1] ~ "(m_uniform_" ~ v ~ ", " ~ uniform_param_list(uniforms[i + 1]) ~ ");" ~
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build(Args...)(Shader s, Args args)
|
||||||
|
{
|
||||||
|
attach_shader(s);
|
||||||
|
build(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build(Args...)(string attrib_name, uint index, Args args)
|
||||||
|
{
|
||||||
|
bind_attrib_location(attrib_name, index);
|
||||||
|
build(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build()
|
||||||
|
{
|
||||||
|
link();
|
||||||
|
}
|
||||||
|
}
|
81
libs/gltk/gltk/shader.d
Normal file
81
libs/gltk/gltk/shader.d
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
module gltk.shader;
|
||||||
|
|
||||||
|
import gl;
|
||||||
|
static import std.file;
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
private GLuint m_id;
|
||||||
|
|
||||||
|
private GLenum m_shader_type;
|
||||||
|
|
||||||
|
this(GLenum shader_type)
|
||||||
|
{
|
||||||
|
m_shader_type = shader_type;
|
||||||
|
m_id = glCreateShader(shader_type);
|
||||||
|
if (m_id == 0u)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to allocate an OpenGL shader");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
glDeleteShader(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_source(const char * source, int length = -1)
|
||||||
|
{
|
||||||
|
GLint status;
|
||||||
|
|
||||||
|
GLint gllength = length;
|
||||||
|
glShaderSource(m_id, 1, &source, &gllength);
|
||||||
|
|
||||||
|
glCompileShader(m_id);
|
||||||
|
|
||||||
|
glGetShaderiv(m_id, GL_COMPILE_STATUS, &status);
|
||||||
|
if (status == GL_TRUE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string message = "Error compiling ";
|
||||||
|
switch (m_shader_type)
|
||||||
|
{
|
||||||
|
case GL_VERTEX_SHADER:
|
||||||
|
message ~= "vertex";
|
||||||
|
break;
|
||||||
|
case GL_FRAGMENT_SHADER:
|
||||||
|
message ~= "fragment";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message ~= "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
message ~= " shader";
|
||||||
|
|
||||||
|
GLint log_length;
|
||||||
|
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
|
if (log_length > 0)
|
||||||
|
{
|
||||||
|
char[] log = new char[log_length];
|
||||||
|
glGetShaderInfoLog(m_id, log_length, &log_length, log.ptr);
|
||||||
|
message ~= "\nShader Log:\n";
|
||||||
|
message ~= log;
|
||||||
|
message ~= "\n";
|
||||||
|
}
|
||||||
|
glDeleteShader(m_id);
|
||||||
|
throw new Exception(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_source_from_file(string filename)
|
||||||
|
{
|
||||||
|
const(char)[] file_data = cast(const(char)[])std.file.read(filename);
|
||||||
|
set_source(file_data.ptr, cast(int)file_data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property GLuint id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
}
|
45
libs/gltk/gltk/texture.d
Normal file
45
libs/gltk/gltk/texture.d
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
module gltk.texture;
|
||||||
|
|
||||||
|
import gl;
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
private GLuint m_id;
|
||||||
|
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
m_id = 0u;
|
||||||
|
glGenTextures(1, &m_id);
|
||||||
|
if (m_id == 0u)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to allocate an OpenGL texture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(GLenum target) const
|
||||||
|
{
|
||||||
|
glBindTexture(target, m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property GLuint id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint next_power_of_2(uint n)
|
||||||
|
{
|
||||||
|
n--;
|
||||||
|
n |= n >> 1u;
|
||||||
|
n |= n >> 2u;
|
||||||
|
n |= n >> 4u;
|
||||||
|
n |= n >> 8u;
|
||||||
|
n |= n >> 16u;
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
};
|
@ -1,7 +1,8 @@
|
|||||||
import std.stdio;
|
import std.stdio;
|
||||||
import sdl;
|
import sdl;
|
||||||
import glad.gl.all;
|
import gl;
|
||||||
import glad.gl.loader;
|
import glad.gl.loader;
|
||||||
|
import gltk;
|
||||||
|
|
||||||
enum int WIDTH = 800;
|
enum int WIDTH = 800;
|
||||||
enum int HEIGHT = 600;
|
enum int HEIGHT = 600;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user