Convert gltk.Program to a class template to generate specialized program classes.
This commit is contained in:
parent
816aca30ac
commit
e215485293
@ -3,10 +3,21 @@ import gltk.shader;
|
|||||||
import derelict.opengl;
|
import derelict.opengl;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
|
||||||
class Program
|
class Program(uniforms...)
|
||||||
{
|
{
|
||||||
|
/* The number of template parameters must be a multiple of 2. */
|
||||||
|
static assert((uniforms.length % 2) == 0);
|
||||||
|
|
||||||
private GLuint m_id;
|
private GLuint m_id;
|
||||||
|
|
||||||
|
static foreach (i, v; uniforms)
|
||||||
|
{
|
||||||
|
static if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
mixin("private GLint m_uniform_" ~ v ~ ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this(Args...)(Args args)
|
this(Args...)(Args args)
|
||||||
{
|
{
|
||||||
m_id = glCreateProgram();
|
m_id = glCreateProgram();
|
||||||
@ -35,7 +46,7 @@ class Program
|
|||||||
glBindAttribLocation(m_id, index, name.toStringz());
|
glBindAttribLocation(m_id, index, name.toStringz());
|
||||||
}
|
}
|
||||||
|
|
||||||
void link() const
|
void link()
|
||||||
{
|
{
|
||||||
glLinkProgram(m_id);
|
glLinkProgram(m_id);
|
||||||
|
|
||||||
@ -56,6 +67,14 @@ class Program
|
|||||||
}
|
}
|
||||||
throw new Exception(message);
|
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
|
GLint get_uniform_location(string uniform_name) const
|
||||||
@ -63,7 +82,7 @@ class Program
|
|||||||
return glGetUniformLocation(m_id, uniform_name.toStringz());
|
return glGetUniformLocation(m_id, uniform_name.toStringz());
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_uniform_locations(Args...)(string uniform_name, GLint * uniform_location, Args args)
|
void get_uniform_locations(Args...)(string uniform_name, GLint * uniform_location, Args args) const
|
||||||
{
|
{
|
||||||
*uniform_location = get_uniform_location(uniform_name);
|
*uniform_location = get_uniform_location(uniform_name);
|
||||||
static if (args.length > 0u)
|
static if (args.length > 0u)
|
||||||
@ -82,19 +101,80 @@ class Program
|
|||||||
glUseProgram(m_id);
|
glUseProgram(m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void build(Args...)(Shader s, Args args) const
|
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);
|
attach_shader(s);
|
||||||
build(args);
|
build(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void build(Args...)(string attrib_name, uint index, Args args) const
|
private void build(Args...)(string attrib_name, uint index, Args args)
|
||||||
{
|
{
|
||||||
bind_attrib_location(attrib_name, index);
|
bind_attrib_location(attrib_name, index);
|
||||||
build(args);
|
build(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void build() const
|
private void build()
|
||||||
{
|
{
|
||||||
link();
|
link();
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,8 @@ import jes.gui.font;
|
|||||||
class Gui
|
class Gui
|
||||||
{
|
{
|
||||||
jtk.Window[] m_windows;
|
jtk.Window[] m_windows;
|
||||||
gltk.Program m_text_program;
|
alias TextProgram = gltk.Program!("viewport_size", "2i", "texture", "1i", "color", "4f", "position", "2i");
|
||||||
GLint m_viewport_size;
|
TextProgram m_text_program;
|
||||||
GLint m_texture;
|
|
||||||
GLint m_color;
|
|
||||||
GLint m_position;
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
@ -47,12 +44,7 @@ class Gui
|
|||||||
v_shader.set_source_from_file("share/jes/shaders/text.v.glsl");
|
v_shader.set_source_from_file("share/jes/shaders/text.v.glsl");
|
||||||
auto f_shader = new gltk.Shader(GL_FRAGMENT_SHADER);
|
auto f_shader = new gltk.Shader(GL_FRAGMENT_SHADER);
|
||||||
f_shader.set_source_from_file("share/jes/shaders/text.f.glsl");
|
f_shader.set_source_from_file("share/jes/shaders/text.f.glsl");
|
||||||
m_text_program = new gltk.Program(v_shader, f_shader, "coords", 0);
|
m_text_program = new TextProgram(v_shader, f_shader, "coords", 0);
|
||||||
m_text_program.get_uniform_locations(
|
|
||||||
"viewport_size", &m_viewport_size,
|
|
||||||
"texture", &m_texture,
|
|
||||||
"color", &m_color,
|
|
||||||
"position", &m_position);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
@ -93,10 +85,10 @@ class Gui
|
|||||||
auto font = new Font("share/jes/fonts/freefont-ttf-20120503/FreeMono.ttf", 20);
|
auto font = new Font("share/jes/fonts/freefont-ttf-20120503/FreeMono.ttf", 20);
|
||||||
auto glyph = font.get_glyph('h');
|
auto glyph = font.get_glyph('h');
|
||||||
m_text_program.use();
|
m_text_program.use();
|
||||||
glUniform2i(m_viewport_size, width, height);
|
m_text_program.set_viewport_size(width, height);
|
||||||
glUniform1i(m_texture, 0);
|
m_text_program.set_texture(0);
|
||||||
glUniform4f(m_color, 1.0, 1.0, 1.0, 1.0);
|
m_text_program.set_color(1.0, 1.0, 1.0, 1.0);
|
||||||
glUniform2i(m_position, 10, 10);
|
m_text_program.set_position(100, 10);
|
||||||
glyph.render();
|
glyph.render();
|
||||||
m_windows[0].swap_buffers();
|
m_windows[0].swap_buffers();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user