|
|
|
@ -31,10 +31,16 @@ namespace
|
|
|
|
|
"layout (location = 0) in vec2 position;\n"
|
|
|
|
|
"layout (location = 1) in vec2 offset;\n"
|
|
|
|
|
"layout (location = 2) in int sprite;\n"
|
|
|
|
|
"layout (location = 3) in vec4 color;\n"
|
|
|
|
|
"layout (location = 4) in float scale;\n"
|
|
|
|
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
|
|
|
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
|
|
|
|
"layout (std430, binding = 0) buffer LayerScales"
|
|
|
|
|
"{\n"
|
|
|
|
|
" float scales[];\n"
|
|
|
|
|
"} lss;\n"
|
|
|
|
|
"layout (std430, binding = 1) buffer LayerColors"
|
|
|
|
|
"{\n"
|
|
|
|
|
" vec4 colors[];\n"
|
|
|
|
|
"} lcs;\n"
|
|
|
|
|
"out VS_OUT {\n"
|
|
|
|
|
" flat int sprite;\n"
|
|
|
|
|
" flat int layer;\n"
|
|
|
|
@ -47,10 +53,10 @@ namespace
|
|
|
|
|
" vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n"
|
|
|
|
|
" vs_out.sprite = sprite;\n"
|
|
|
|
|
" vs_out.layer = layer;\n"
|
|
|
|
|
" vs_out.layer_color = color;\n"
|
|
|
|
|
" vs_out.layer_color = lcs.colors[layer];\n"
|
|
|
|
|
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n"
|
|
|
|
|
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z));\n"
|
|
|
|
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(0.5, -0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
|
|
|
|
" vec2 cell_position = vec2(lss.scales[layer] + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z));\n"
|
|
|
|
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * lss.scales[layer] + cell_position + vec2(0.5, -0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
|
|
|
|
" gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n"
|
|
|
|
|
"}";
|
|
|
|
|
|
|
|
|
@ -62,10 +68,16 @@ namespace
|
|
|
|
|
"layout (location = 0) in vec2 position;\n"
|
|
|
|
|
"layout (location = 1) in vec2 offset;\n"
|
|
|
|
|
"layout (location = 2) in int sprite;\n"
|
|
|
|
|
"layout (location = 3) in vec4 color;\n"
|
|
|
|
|
"layout (location = 4) in float scale;\n"
|
|
|
|
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
|
|
|
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
|
|
|
|
"layout (std430, binding = 0) buffer LayerScales"
|
|
|
|
|
"{\n"
|
|
|
|
|
" float scales[];\n"
|
|
|
|
|
"} lss;\n"
|
|
|
|
|
"layout (std430, binding = 1) buffer LayerColors"
|
|
|
|
|
"{\n"
|
|
|
|
|
" vec4 colors[];\n"
|
|
|
|
|
"} lcs;\n"
|
|
|
|
|
"out VS_OUT {\n"
|
|
|
|
|
" flat int sprite;\n"
|
|
|
|
|
" flat vec4 layer_color;\n"
|
|
|
|
@ -78,9 +90,9 @@ namespace
|
|
|
|
|
" vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n"
|
|
|
|
|
" vs_out.sprite = sprite;\n"
|
|
|
|
|
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n"
|
|
|
|
|
" vs_out.layer_color = color;\n"
|
|
|
|
|
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z));\n"
|
|
|
|
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(0.5, -0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
|
|
|
|
" vs_out.layer_color = lcs.colors[layer];\n"
|
|
|
|
|
" vec2 cell_position = vec2(lss.scales[layer] + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) * " GRID_SIZE_UNIFORM_NAME ".z));\n"
|
|
|
|
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * lss.scales[layer] + cell_position + vec2(0.5, -0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
|
|
|
|
" gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n"
|
|
|
|
|
"}";
|
|
|
|
|
|
|
|
|
@ -196,8 +208,8 @@ namespace glerminal
|
|
|
|
|
m_cells{ },
|
|
|
|
|
m_offsets{ },
|
|
|
|
|
m_sprites{ },
|
|
|
|
|
m_colors{ },
|
|
|
|
|
m_scales{ }
|
|
|
|
|
m_layer_colors{ },
|
|
|
|
|
m_layer_scales{ }
|
|
|
|
|
#ifdef GLERMINAL_OPENGL_DEBUG_CONTEXT
|
|
|
|
|
, m_log("log.txt")
|
|
|
|
|
#endif
|
|
|
|
@ -218,10 +230,10 @@ namespace glerminal
|
|
|
|
|
throw std::runtime_error("No main callback provided.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < GRID_AREA * LAYER_COUNT; i++)
|
|
|
|
|
for (int i = 0; i < LAYER_COUNT; i++)
|
|
|
|
|
{
|
|
|
|
|
m_colors[i * 4 + 0] = m_colors[i * 4 + 1] = m_colors[i * 4 + 2] = m_colors[i * 4 + 3] = 255;
|
|
|
|
|
m_scales[i] = 1;
|
|
|
|
|
m_layer_colors[i * 4 + 0] = m_layer_colors[i * 4 + 1] = m_layer_colors[i * 4 + 2] = m_layer_colors[i * 4 + 3] = 1;
|
|
|
|
|
m_layer_scales[i] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init_glfw();
|
|
|
|
@ -262,11 +274,11 @@ namespace glerminal
|
|
|
|
|
|
|
|
|
|
void glerminal::flush()
|
|
|
|
|
{
|
|
|
|
|
glNamedBufferSubData(m_sprites_instance_vbo, 0, sizeof(m_cells), m_cells);
|
|
|
|
|
glNamedBufferSubData(m_offsets_instance_vbo, 0, sizeof(m_offsets), m_offsets);
|
|
|
|
|
glNamedBufferData(m_sprites_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
|
|
|
|
|
glNamedBufferData(m_offsets_instance_vbo, sizeof(m_offsets), m_offsets, GL_STREAM_DRAW);
|
|
|
|
|
update_sprites();
|
|
|
|
|
update_colors();
|
|
|
|
|
update_scales();
|
|
|
|
|
update_layer_colors();
|
|
|
|
|
update_layer_scales();
|
|
|
|
|
|
|
|
|
|
glUseProgram(m_program);
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
@ -318,17 +330,17 @@ namespace glerminal
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color)
|
|
|
|
|
void glerminal::layer_color(unsigned char layer, unsigned int color)
|
|
|
|
|
{
|
|
|
|
|
m_colors[4 * (x + y * GRID_WIDTH + layer * GRID_AREA) + 0] = ((color >> 0) & 0xFF);
|
|
|
|
|
m_colors[4 * (x + y * GRID_WIDTH + layer * GRID_AREA) + 1] = ((color >> 8) & 0xFF);
|
|
|
|
|
m_colors[4 * (x + y * GRID_WIDTH + layer * GRID_AREA) + 2] = ((color >> 16) & 0xFF);
|
|
|
|
|
m_colors[4 * (x + y * GRID_WIDTH + layer * GRID_AREA) + 3] = ((color >> 24) & 0xFF);
|
|
|
|
|
m_layer_colors[layer * 4 + 0] = ((color >> 0) & 0xFF) / 255.0f;
|
|
|
|
|
m_layer_colors[layer * 4 + 1] = ((color >> 8) & 0xFF) / 255.0f;
|
|
|
|
|
m_layer_colors[layer * 4 + 2] = ((color >> 16) & 0xFF) / 255.0f;
|
|
|
|
|
m_layer_colors[layer * 4 + 3] = ((color >> 24) & 0xFF) / 255.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::scale(unsigned char x, unsigned char y, unsigned char layer, float scale)
|
|
|
|
|
void glerminal::layer_scale(unsigned char layer, float scale)
|
|
|
|
|
{
|
|
|
|
|
m_scales[x + y * GRID_WIDTH + layer * GRID_AREA] = scale;
|
|
|
|
|
m_layer_scales[layer] = scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::load_atlas(unsigned char w, unsigned char h, const unsigned int* data)
|
|
|
|
@ -395,6 +407,7 @@ namespace glerminal
|
|
|
|
|
void glerminal::init_gl()
|
|
|
|
|
{
|
|
|
|
|
glfwMakeContextCurrent(m_window);
|
|
|
|
|
glfwSwapInterval(1);
|
|
|
|
|
|
|
|
|
|
if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress)))
|
|
|
|
|
{
|
|
|
|
@ -469,8 +482,8 @@ namespace glerminal
|
|
|
|
|
glGenBuffers(1, &m_vbo);
|
|
|
|
|
glGenBuffers(1, &m_sprites_instance_vbo);
|
|
|
|
|
glGenBuffers(1, &m_offsets_instance_vbo);
|
|
|
|
|
glGenBuffers(1, &m_colors_instance_vbo);
|
|
|
|
|
glGenBuffers(1, &m_scales_instance_vbo);
|
|
|
|
|
glGenBuffers(1, &m_layer_colors_buffer);
|
|
|
|
|
glGenBuffers(1, &m_layer_scales_buffer);
|
|
|
|
|
|
|
|
|
|
// create vertex array object
|
|
|
|
|
glGenVertexArrays(1, &m_vao);
|
|
|
|
@ -478,35 +491,23 @@ namespace glerminal
|
|
|
|
|
|
|
|
|
|
// set up static vertex attributes
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
|
|
|
|
glBufferStorage(GL_ARRAY_BUFFER, sizeof(VBO_VERTICES), VBO_VERTICES, GL_NONE);
|
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(VBO_VERTICES), VBO_VERTICES, GL_STATIC_DRAW);
|
|
|
|
|
glEnableVertexAttribArray(0);
|
|
|
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(*VBO_VERTICES), reinterpret_cast<void*>(0));
|
|
|
|
|
|
|
|
|
|
// set up instanced vertex attributes
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_offsets_instance_vbo);
|
|
|
|
|
glBufferStorage(GL_ARRAY_BUFFER, sizeof(m_offsets), m_offsets, GL_DYNAMIC_STORAGE_BIT);
|
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(m_offsets), m_offsets, GL_STREAM_DRAW);
|
|
|
|
|
glEnableVertexAttribArray(1);
|
|
|
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(*m_offsets), reinterpret_cast<void*>(0));
|
|
|
|
|
glVertexAttribDivisor(1, 1);
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_sprites_instance_vbo);
|
|
|
|
|
glBufferStorage(GL_ARRAY_BUFFER, sizeof(m_cells), m_cells, GL_DYNAMIC_STORAGE_BIT);
|
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
|
|
|
|
|
glEnableVertexAttribArray(2);
|
|
|
|
|
glVertexAttribIPointer(2, 1, GL_UNSIGNED_SHORT, 1 * sizeof(*m_cells), reinterpret_cast<void*>(0));
|
|
|
|
|
glVertexAttribDivisor(2, 1);
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_colors_instance_vbo);
|
|
|
|
|
glBufferStorage(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, GL_DYNAMIC_STORAGE_BIT);
|
|
|
|
|
glEnableVertexAttribArray(3);
|
|
|
|
|
glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(*m_colors), reinterpret_cast<void*>(0));
|
|
|
|
|
glVertexAttribDivisor(3, 1);
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_scales_instance_vbo);
|
|
|
|
|
glBufferStorage(GL_ARRAY_BUFFER, sizeof(m_scales), m_scales, GL_DYNAMIC_STORAGE_BIT);
|
|
|
|
|
glEnableVertexAttribArray(4);
|
|
|
|
|
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, 1 * sizeof(*m_scales), reinterpret_cast<void*>(0));
|
|
|
|
|
glVertexAttribDivisor(4, 1);
|
|
|
|
|
|
|
|
|
|
// set up static vertex attributes
|
|
|
|
|
glGenVertexArrays(1, &m_screen_vao);
|
|
|
|
|
glBindVertexArray(m_screen_vao);
|
|
|
|
@ -517,6 +518,14 @@ namespace glerminal
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_layer_scales_buffer);
|
|
|
|
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_layer_scales), m_layer_scales, GL_DYNAMIC_READ);
|
|
|
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_layer_scales_buffer);
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_layer_colors_buffer);
|
|
|
|
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_layer_colors), m_layer_colors, GL_DYNAMIC_READ);
|
|
|
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_layer_colors_buffer);
|
|
|
|
|
|
|
|
|
|
// -- setup shader program --
|
|
|
|
|
// test for features
|
|
|
|
|
const bool vertex_shader_layer_supported =
|
|
|
|
@ -756,8 +765,8 @@ namespace glerminal
|
|
|
|
|
glDeleteBuffers(1, &m_vbo);
|
|
|
|
|
glDeleteBuffers(1, &m_sprites_instance_vbo);
|
|
|
|
|
glDeleteBuffers(1, &m_offsets_instance_vbo);
|
|
|
|
|
glDeleteBuffers(1, &m_colors_instance_vbo);
|
|
|
|
|
glDeleteBuffers(1, &m_scales_instance_vbo);
|
|
|
|
|
glDeleteBuffers(1, &m_layer_colors_buffer);
|
|
|
|
|
glDeleteBuffers(1, &m_layer_scales_buffer);
|
|
|
|
|
glDeleteProgram(m_program);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -766,14 +775,14 @@ namespace glerminal
|
|
|
|
|
glTextureSubImage2D(m_sprites_texture, 0, 0, 0, (CELL_SIZE + 2) * MAX_SPRITES_ROW, (CELL_SIZE + 2) * MAX_SPRITES_ROW, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::update_colors()
|
|
|
|
|
void glerminal::update_layer_colors()
|
|
|
|
|
{
|
|
|
|
|
glNamedBufferSubData(m_colors_instance_vbo, 0, sizeof(m_colors), m_colors);
|
|
|
|
|
glNamedBufferData(m_layer_colors_buffer, sizeof(m_layer_colors), m_layer_colors, GL_DYNAMIC_READ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::update_scales()
|
|
|
|
|
void glerminal::update_layer_scales()
|
|
|
|
|
{
|
|
|
|
|
glNamedBufferSubData(m_scales_instance_vbo, 0, sizeof(m_scales), m_scales);
|
|
|
|
|
glNamedBufferData(m_layer_scales_buffer, sizeof(m_layer_scales), m_layer_scales, GL_DYNAMIC_READ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal::glfw_key_handler(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
|
|
@ -841,18 +850,18 @@ void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, flo
|
|
|
|
|
GLERMINAL_G->offset(x, y, layer, x_offset, y_offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal_color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color)
|
|
|
|
|
void glerminal_layer_color(unsigned char layer, unsigned int color)
|
|
|
|
|
{
|
|
|
|
|
if (!GLERMINAL_G) { return; }
|
|
|
|
|
|
|
|
|
|
GLERMINAL_G->color(x, y, layer, color);
|
|
|
|
|
GLERMINAL_G->layer_color(layer, color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void glerminal_scale(unsigned char x, unsigned char y, unsigned char layer, float scale)
|
|
|
|
|
void glerminal_layer_scale(unsigned char layer, float scale)
|
|
|
|
|
{
|
|
|
|
|
if (!GLERMINAL_G) { return; }
|
|
|
|
|
|
|
|
|
|
GLERMINAL_G->scale(x, y, layer, scale);
|
|
|
|
|
GLERMINAL_G->layer_scale(layer, scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int glerminal_load_sprites_file(const char* filename)
|
|
|
|
|