Add demo shader and spinning colored cube
This commit is contained in:
parent
8e6ec5f820
commit
8dc6e97585
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
|||||||
[submodule "libs/bindbc-common"]
|
[submodule "libs/bindbc-common"]
|
||||||
path = libs/bindbc-common
|
path = libs/bindbc-common
|
||||||
url = https://github.com/BindBC/bindbc-common
|
url = https://github.com/BindBC/bindbc-common
|
||||||
|
[submodule "libs/gl3n"]
|
||||||
|
path = libs/gl3n
|
||||||
|
url = https://github.com/holtrop/gl3n
|
||||||
|
@ -13,8 +13,10 @@ env "app" do |env|
|
|||||||
sources = dirs.reduce([]) do |result, dir|
|
sources = dirs.reduce([]) do |result, dir|
|
||||||
result + glob("#{dir}/**/*.{d,c}")
|
result + glob("#{dir}/**/*.{d,c}")
|
||||||
end
|
end
|
||||||
|
sources += glob("libs/gl3n/gl3n/**/*.{d,c}")
|
||||||
env["D_IMPORT_PATH"] += dirs
|
env["D_IMPORT_PATH"] += dirs
|
||||||
env["DFLAGS"] += %w[--d-version=BindBC_Static --d-version=SDL_208]
|
env["D_IMPORT_PATH"] += ["libs/gl3n"]
|
||||||
|
env["DFLAGS"] += %w[--d-version=BindBC_Static --d-version=SDL_208 -g]
|
||||||
env["LDFLAGS"] += %w[-L-lfreetype -L-lSDL2]
|
env["LDFLAGS"] += %w[-L-lfreetype -L-lSDL2]
|
||||||
env.Program("^/app", sources)
|
env.Program("^/app", sources)
|
||||||
end
|
end
|
||||||
|
1
libs/gl3n
Submodule
1
libs/gl3n
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit cb233335f50d9cc12f055715b9b42955bf3d379e
|
@ -34,7 +34,7 @@ class Array
|
|||||||
/**
|
/**
|
||||||
* Bind array.
|
* Bind array.
|
||||||
*/
|
*/
|
||||||
void bind() const
|
public void bind() const
|
||||||
{
|
{
|
||||||
glBindVertexArray(m_id);
|
glBindVertexArray(m_id);
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ class Array
|
|||||||
/**
|
/**
|
||||||
* Get array ID.
|
* Get array ID.
|
||||||
*/
|
*/
|
||||||
@property GLuint id() const
|
public @property GLuint id() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,22 @@ import gl;
|
|||||||
/**
|
/**
|
||||||
* OpenGL buffer object.
|
* OpenGL buffer object.
|
||||||
*/
|
*/
|
||||||
class Buffer
|
class BufferBase(GLenum target = GL_ARRAY_BUFFER)
|
||||||
{
|
{
|
||||||
/** Buffer ID. */
|
/** Buffer ID. */
|
||||||
private GLuint m_id;
|
private GLuint m_id;
|
||||||
|
|
||||||
/** Buffer target. */
|
|
||||||
private GLenum m_target;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct buffer.
|
* Construct buffer.
|
||||||
*
|
*
|
||||||
* @param target
|
* @param data
|
||||||
* OpenGL buffer target (e.g. GL_ARRAY_BUFFER, GL_ELEMENT_BUFFER)
|
* Buffer data.
|
||||||
|
* @param size
|
||||||
|
* Buffer data size.
|
||||||
|
* @param usage
|
||||||
|
* OpenGL buffer usage (default is GL_STATIC_DRAW)
|
||||||
*/
|
*/
|
||||||
this(GLenum target)
|
this(const(void) * data = null, size_t size, GLenum usage = GL_STATIC_DRAW)
|
||||||
{
|
{
|
||||||
m_id = 0u;
|
m_id = 0u;
|
||||||
glGenBuffers(1, &m_id);
|
glGenBuffers(1, &m_id);
|
||||||
@ -27,7 +28,31 @@ class Buffer
|
|||||||
{
|
{
|
||||||
throw new Exception("Failed to allocate an OpenGL buffer");
|
throw new Exception("Failed to allocate an OpenGL buffer");
|
||||||
}
|
}
|
||||||
m_target = target;
|
bind();
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
set_buffer_data(data, size, usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct buffer.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* Buffer data.
|
||||||
|
* @param usage
|
||||||
|
* OpenGL buffer usage (default is GL_STATIC_DRAW)
|
||||||
|
*/
|
||||||
|
this(T)(const(T)[] data = null, GLenum usage = GL_STATIC_DRAW)
|
||||||
|
{
|
||||||
|
if (data is null)
|
||||||
|
{
|
||||||
|
this(null, 0u, usage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this(data.ptr, data.length * data[0].sizeof, usage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,15 +66,15 @@ class Buffer
|
|||||||
/**
|
/**
|
||||||
* Bind buffer.
|
* Bind buffer.
|
||||||
*/
|
*/
|
||||||
void bind() const
|
public void bind() const
|
||||||
{
|
{
|
||||||
glBindBuffer(m_target, m_id);
|
glBindBuffer(target, m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get buffer ID.
|
* Get buffer ID.
|
||||||
*/
|
*/
|
||||||
@property GLuint id() const
|
public @property GLuint id() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
@ -57,28 +82,43 @@ class Buffer
|
|||||||
/**
|
/**
|
||||||
* Set buffer data.
|
* Set buffer data.
|
||||||
*
|
*
|
||||||
* @param usage
|
* @param data
|
||||||
* OpenGL buffer usage (e.g. GL_STATIC_DRAW, ...)
|
|
||||||
* @param ptr
|
|
||||||
* Pointer to buffer data.
|
* Pointer to buffer data.
|
||||||
* @param size
|
* @param size
|
||||||
* Buffer data size.
|
* Buffer data size.
|
||||||
|
* @param usage
|
||||||
|
* OpenGL buffer usage (default is GL_STATIC_DRAW)
|
||||||
*/
|
*/
|
||||||
void set_buffer_data(GLenum usage, const void * ptr, size_t size)
|
public void set_buffer_data(const(void) * data, size_t size, GLenum usage = GL_STATIC_DRAW) const
|
||||||
{
|
{
|
||||||
glNamedBufferData(m_id, size, ptr, usage);
|
glBufferData(target, size, data, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set buffer data.
|
* Set buffer data.
|
||||||
*
|
*
|
||||||
|
* @param data
|
||||||
|
* Buffer data.
|
||||||
* @param usage
|
* @param usage
|
||||||
* OpenGL buffer usage (e.g. GL_STATIC_DRAW, ...)
|
* OpenGL buffer usage (e.g. GL_STATIC_DRAW, ...)
|
||||||
* @param array
|
|
||||||
* Buffer data.
|
|
||||||
*/
|
*/
|
||||||
void set_buffer_data(T)(GLenum usage, T[] arr)
|
public void set_buffer_data(T)(const(T)[] data, GLenum usage = GL_STATIC_DRAW) const
|
||||||
{
|
{
|
||||||
glNamedBufferData(m_id, arr.length * arr[0].sizeof, arr.ptr, usage);
|
glBufferData(target, data.length * data[0].sizeof, data.ptr, usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience class alias for a Buffer with a GL_ARRAY_BUFFER target.
|
||||||
|
*/
|
||||||
|
alias Buffer = BufferBase!(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience class alias for a Buffer with a GL_ELEMENT_ARRAY_BUFFER target.
|
||||||
|
*/
|
||||||
|
alias ElementBuffer = BufferBase!(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience class alias for a Buffer with a GL_UNIFORM_BUFFER target.
|
||||||
|
*/
|
||||||
|
alias UniformBuffer = BufferBase!(GL_UNIFORM_BUFFER);
|
||||||
|
@ -20,7 +20,7 @@ import gl;
|
|||||||
* Attributes are specified as an associative array with attribute names as
|
* Attributes are specified as an associative array with attribute names as
|
||||||
* keys and attribute locations as values.
|
* keys and attribute locations as values.
|
||||||
*/
|
*/
|
||||||
class Program(string[string] uniforms = [], int[string] attributes = [])
|
class Program(alias uniforms = [], alias attributes = [])
|
||||||
{
|
{
|
||||||
/** Program ID. */
|
/** Program ID. */
|
||||||
private GLuint m_id;
|
private GLuint m_id;
|
||||||
@ -151,13 +151,13 @@ class Program(string[string] uniforms = [], int[string] attributes = [])
|
|||||||
mixin("private GLint m_uniform_" ~ uniform_name ~ ";");
|
mixin("private GLint m_uniform_" ~ uniform_name ~ ";");
|
||||||
mixin("public void set_" ~ uniform_name ~ "(" ~ uniform_param_decl_list(uniform_type) ~ ") const" ~
|
mixin("public void set_" ~ uniform_name ~ "(" ~ uniform_param_decl_list(uniform_type) ~ ") const" ~
|
||||||
"{" ~
|
"{" ~
|
||||||
" glProgramUniform" ~ uniform_type ~ "(m_id, m_uniform_" ~ uniform_name ~ ", " ~ (uniform_type_info(uniform_type).v ? "1, " : "") ~ (uniform_type_info(uniform_type).matrix ? "false, " : "") ~ uniform_param_list(uniform_type) ~ ");" ~
|
" glProgramUniform" ~ uniform_type ~ "(m_id, m_uniform_" ~ uniform_name ~ ", " ~ (uniform_type_info(uniform_type).v ? "1, " : "") ~ (uniform_type_info(uniform_type).matrix ? "GL_FALSE, " : "") ~ uniform_param_list(uniform_type) ~ ");" ~
|
||||||
"}");
|
"}");
|
||||||
static if (uniform_type_info(uniform_type).v)
|
static if (uniform_type_info(uniform_type).v)
|
||||||
{
|
{
|
||||||
mixin("public void set_" ~ uniform_name ~ "(GLsizei count, " ~ uniform_param_decl_list(uniform_type) ~ ") const" ~
|
mixin("public void set_" ~ uniform_name ~ "(GLsizei count, " ~ uniform_param_decl_list(uniform_type) ~ ") const" ~
|
||||||
"{" ~
|
"{" ~
|
||||||
" glProgramUniform" ~ uniform_type ~ "(m_id, m_uniform_" ~ uniform_name ~ ", count, " ~ (uniform_type_info(uniform_type).matrix ? "false, " : "") ~ uniform_param_list(uniform_type) ~ ");" ~
|
" glProgramUniform" ~ uniform_type ~ "(m_id, m_uniform_" ~ uniform_name ~ ", count, " ~ (uniform_type_info(uniform_type).matrix ? "GL_FALSE, " : "") ~ uniform_param_list(uniform_type) ~ ");" ~
|
||||||
"}");
|
"}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,10 +346,12 @@ class Program(string[string] uniforms = [], int[string] attributes = [])
|
|||||||
else if (shader_type != 0)
|
else if (shader_type != 0)
|
||||||
{
|
{
|
||||||
shader_source ~= line;
|
shader_source ~= line;
|
||||||
|
shader_source ~= "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
common_source ~= line;
|
common_source ~= line;
|
||||||
|
common_source ~= "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +43,20 @@ class Shader
|
|||||||
string message = "Error compiling ";
|
string message = "Error compiling ";
|
||||||
switch (shader_type)
|
switch (shader_type)
|
||||||
{
|
{
|
||||||
case GL_VERTEX_SHADER:
|
case GL_VERTEX_SHADER:
|
||||||
message ~= "vertex";
|
message ~= "vertex";
|
||||||
break;
|
break;
|
||||||
case GL_FRAGMENT_SHADER:
|
case GL_FRAGMENT_SHADER:
|
||||||
message ~= "fragment";
|
message ~= "fragment";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
message ~= "unknown";
|
message ~= "unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
message ~= " shader";
|
message ~= " shader:\n";
|
||||||
|
message ~= "---\n";
|
||||||
|
message ~= source;
|
||||||
|
message ~= "---\n";
|
||||||
|
|
||||||
GLint log_length;
|
GLint log_length;
|
||||||
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
@ -61,7 +64,7 @@ class Shader
|
|||||||
{
|
{
|
||||||
char[] log = new char[log_length];
|
char[] log = new char[log_length];
|
||||||
glGetShaderInfoLog(m_id, log_length, &log_length, log.ptr);
|
glGetShaderInfoLog(m_id, log_length, &log_length, log.ptr);
|
||||||
message ~= "\nShader Log:\n";
|
message ~= "Shader Log:\n";
|
||||||
message ~= log;
|
message ~= log;
|
||||||
message ~= "\n";
|
message ~= "\n";
|
||||||
}
|
}
|
||||||
@ -80,7 +83,7 @@ class Shader
|
|||||||
/**
|
/**
|
||||||
* Get shader ID.
|
* Get shader ID.
|
||||||
*/
|
*/
|
||||||
@property GLuint id() const
|
public @property GLuint id() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
60
src/app.d
60
src/app.d
@ -3,10 +3,17 @@ import sdl;
|
|||||||
import gl;
|
import gl;
|
||||||
import glad.gl.loader;
|
import glad.gl.loader;
|
||||||
import gltk;
|
import gltk;
|
||||||
|
import gl3n.linalg;
|
||||||
|
|
||||||
enum int WIDTH = 800;
|
enum int WIDTH = 800;
|
||||||
enum int HEIGHT = 600;
|
enum int HEIGHT = 600;
|
||||||
|
|
||||||
|
alias ColorShader = Program!(["view": "Matrix4fv"], ["position": 0, "color": 1]);
|
||||||
|
ColorShader color_shader;
|
||||||
|
Array spinny_vao;
|
||||||
|
GLuint program_id;
|
||||||
|
mat4 view_matrix;
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@ -15,12 +22,65 @@ void init()
|
|||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glClearColor (1.0, 0.6, 0.0, 0.0);
|
glClearColor (1.0, 0.6, 0.0, 0.0);
|
||||||
glViewport(0, 0, WIDTH, HEIGHT);
|
glViewport(0, 0, WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
spinny_vao = new Array();
|
||||||
|
spinny_vao.bind();
|
||||||
|
string color_program_src = `
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
vertex:
|
||||||
|
in vec2 position;
|
||||||
|
in vec4 color;
|
||||||
|
out vec4 color_i;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = view * vec4(position, 0.0, 1.0);
|
||||||
|
color_i = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment:
|
||||||
|
in vec4 color_i;
|
||||||
|
out vec4 frag_color;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
frag_color = color_i;
|
||||||
|
}`;
|
||||||
|
color_shader = new ColorShader(color_program_src);
|
||||||
|
color_shader.use();
|
||||||
|
|
||||||
|
float[] vertices = [0.4, 0.4, -0.4, 0.4, -0.4, -0.4, 0.4, -0.4];
|
||||||
|
float[] colors = [
|
||||||
|
1.0, 0.0, 0.0, 1.0,
|
||||||
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
0.0, 0.0, 1.0, 1.0,
|
||||||
|
1.0, 1.0, 1.0, 1.0];
|
||||||
|
ushort[] indices = [0, 1, 2, 3];
|
||||||
|
Buffer vbo = new Buffer(vertices);
|
||||||
|
vbo.bind();
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, null);
|
||||||
|
Buffer cbo = new Buffer(colors);
|
||||||
|
cbo.bind();
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, null);
|
||||||
|
ElementBuffer ibo = new ElementBuffer(indices);
|
||||||
|
ibo.bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void display(SDL_Window * window)
|
void display(SDL_Window * window)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
color_shader.use();
|
||||||
|
spinny_vao.bind();
|
||||||
|
view_matrix.make_identity();
|
||||||
|
view_matrix.scale(HEIGHT / cast(float)WIDTH, 1.0, 1.0);
|
||||||
|
view_matrix.rotatez(SDL_GetTicks() / 500.0);
|
||||||
|
color_shader.set_view(view_matrix.value_ptr);
|
||||||
|
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, null);
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user