Add demo shader and spinning colored cube

This commit is contained in:
Josh Holtrop 2024-01-25 20:57:33 -05:00
parent 8e6ec5f820
commit 8dc6e97585
8 changed files with 149 additions and 38 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "libs/bindbc-common"]
path = libs/bindbc-common
url = https://github.com/BindBC/bindbc-common
[submodule "libs/gl3n"]
path = libs/gl3n
url = https://github.com/holtrop/gl3n

View File

@ -13,8 +13,10 @@ env "app" do |env|
sources = dirs.reduce([]) do |result, dir|
result + glob("#{dir}/**/*.{d,c}")
end
sources += glob("libs/gl3n/gl3n/**/*.{d,c}")
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.Program("^/app", sources)
end

1
libs/gl3n Submodule

@ -0,0 +1 @@
Subproject commit cb233335f50d9cc12f055715b9b42955bf3d379e

View File

@ -34,7 +34,7 @@ class Array
/**
* Bind array.
*/
void bind() const
public void bind() const
{
glBindVertexArray(m_id);
}
@ -42,7 +42,7 @@ class Array
/**
* Get array ID.
*/
@property GLuint id() const
public @property GLuint id() const
{
return m_id;
}

View File

@ -5,21 +5,22 @@ import gl;
/**
* OpenGL buffer object.
*/
class Buffer
class BufferBase(GLenum target = GL_ARRAY_BUFFER)
{
/** Buffer ID. */
private GLuint m_id;
/** Buffer target. */
private GLenum m_target;
/**
* Construct buffer.
*
* @param target
* OpenGL buffer target (e.g. GL_ARRAY_BUFFER, GL_ELEMENT_BUFFER)
* @param data
* 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;
glGenBuffers(1, &m_id);
@ -27,7 +28,31 @@ class 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.
*/
void bind() const
public void bind() const
{
glBindBuffer(m_target, m_id);
glBindBuffer(target, m_id);
}
/**
* Get buffer ID.
*/
@property GLuint id() const
public @property GLuint id() const
{
return m_id;
}
@ -57,28 +82,43 @@ class Buffer
/**
* Set buffer data.
*
* @param usage
* OpenGL buffer usage (e.g. GL_STATIC_DRAW, ...)
* @param ptr
* @param data
* Pointer to buffer data.
* @param 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.
*
* @param data
* Buffer data.
* @param usage
* 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);

View File

@ -20,7 +20,7 @@ import gl;
* Attributes are specified as an associative array with attribute names as
* keys and attribute locations as values.
*/
class Program(string[string] uniforms = [], int[string] attributes = [])
class Program(alias uniforms = [], alias attributes = [])
{
/** Program 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("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)
{
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)
{
shader_source ~= line;
shader_source ~= "\n";
}
else
{
common_source ~= line;
common_source ~= "\n";
}
}

View File

@ -53,7 +53,10 @@ class Shader
message ~= "unknown";
break;
}
message ~= " shader";
message ~= " shader:\n";
message ~= "---\n";
message ~= source;
message ~= "---\n";
GLint log_length;
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
@ -61,7 +64,7 @@ class Shader
{
char[] log = new char[log_length];
glGetShaderInfoLog(m_id, log_length, &log_length, log.ptr);
message ~= "\nShader Log:\n";
message ~= "Shader Log:\n";
message ~= log;
message ~= "\n";
}
@ -80,7 +83,7 @@ class Shader
/**
* Get shader ID.
*/
@property GLuint id() const
public @property GLuint id() const
{
return m_id;
}

View File

@ -3,10 +3,17 @@ import sdl;
import gl;
import glad.gl.loader;
import gltk;
import gl3n.linalg;
enum int WIDTH = 800;
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()
{
glActiveTexture(GL_TEXTURE0);
@ -15,12 +22,65 @@ void init()
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glClearColor (1.0, 0.6, 0.0, 0.0);
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)
{
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);
}