Compare commits

..

2 Commits

Author SHA1 Message Date
Shylie
996d14c93c Correctly initialize m_colors and m_scales 2024-06-07 12:36:27 -04:00
Shylie
d50fefc359 Make tinting and scaling per-cell instead of per-layer 2024-06-07 12:33:23 -04:00
6 changed files with 91 additions and 104 deletions

View File

@ -18,21 +18,15 @@ namespace
{ {
glerminal_load_sprites_file("resources/rogue.png"); glerminal_load_sprites_file("resources/rogue.png");
for (int i = 0; i < WALL_LAYERS; i++)
{
const unsigned char v = (i + 1) * (256 / WALL_LAYERS) - 1;
const unsigned int j = (0xFF << 24) | (v << 16) | (v << 8) | v;
glerminal_layer_color(i, j);
glerminal_layer_scale(i, (i / static_cast<float>(WALL_LAYERS)) + 1);
}
for (int i = 0; i < GRID_WIDTH; i++) for (int i = 0; i < GRID_WIDTH; i++)
{ {
for (int j = 0; j < GRID_HEIGHT; j++) for (int j = 0; j < GRID_HEIGHT; j++)
{ {
for (int k = 0; k < WALL_LAYERS; k++) for (int k = 0; k < WALL_LAYERS; k++)
{ {
const unsigned char v = (k + 1) * (256 / WALL_LAYERS) - 1;
const unsigned int c = (0xFF << 24) | (v << 16) | (v << 8) | v;
if (i == 0 || j == 0 || i == GRID_WIDTH - 1 || j == GRID_HEIGHT - 1) if (i == 0 || j == 0 || i == GRID_WIDTH - 1 || j == GRID_HEIGHT - 1)
{ {
glerminal_set(i, j, k, floor); glerminal_set(i, j, k, floor);
@ -41,6 +35,9 @@ namespace
{ {
glerminal_set(i, j, k, wall); glerminal_set(i, j, k, wall);
} }
glerminal_color(i, j, k, c);
glerminal_scale(i, j, k, (k / static_cast<float>(WALL_LAYERS)) + 1);
} }
} }
} }

View File

@ -11,14 +11,6 @@ namespace
glerminal_load_sprites_file("resources/towers.png"); glerminal_load_sprites_file("resources/towers.png");
for (int i = 0; i < LAYER_COUNT; i++)
{
constexpr unsigned char c = 16;
const unsigned char v = (255 - c) * powf((256 / LAYER_COUNT * i - 1) / 256.0f, 2.0f) + c;
const unsigned int j = (0xFF << 24) | (v << 16) | (v << 8) | v;
glerminal_layer_color(i, j);
glerminal_layer_scale(i, i / static_cast<float>(LAYER_COUNT) + 1);
}
for (int i = 0; i < GRID_WIDTH; i++) for (int i = 0; i < GRID_WIDTH; i++)
{ {
@ -29,6 +21,15 @@ namespace
{ {
glerminal_set(i, j, k, 1); glerminal_set(i, j, k, 1);
} }
for (int k = 0; k < LAYER_COUNT; k++)
{
constexpr unsigned char min = 16;
const unsigned char v = (255 - min) * powf((256 / LAYER_COUNT * k - 1) / 256.0f, 2.0f) + min;
const unsigned int col = (0xFF << 24) | (v << 16) | (v << 8) | v;
glerminal_color(i, j, k, col);
glerminal_scale(i, j, k, k / static_cast<float>(LAYER_COUNT) + 1);
}
} }
} }
} }

View File

@ -59,13 +59,13 @@ void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, flo
* @param layer The layer to modify * @param layer The layer to modify
* @param color The new color * @param color The new color
*/ */
void glerminal_layer_color(unsigned char layer, unsigned int color); void glerminal_color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color);
/** /**
* @brief Set a layer's scale * @brief Set a layer's scale
* @param layer The layer to modify * @param layer The layer to modify
* @param scale The new scale * @param scale The new scale
*/ */
void glerminal_layer_scale(unsigned char layer, float scale); void glerminal_scale(unsigned char x, unsigned char y, unsigned char layer, float scale);
/** /**
* @brief Load sprites from a png file * @brief Load sprites from a png file

View File

@ -71,18 +71,22 @@ namespace
int lglerminal_layer_color(lua_State* L) int lglerminal_layer_color(lua_State* L)
{ {
const unsigned char layer = luaL_checkinteger(L, 1) - 1; const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned int color = luaL_checkinteger(L, 2); const unsigned char y = luaL_checkinteger(L, 2) - 1;
glerminal_layer_color(layer, color); const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const unsigned int color = luaL_checkinteger(L, 4);
glerminal_color(x, y, layer, color);
return 0; return 0;
} }
int lglerminal_layer_scale(lua_State* L) int lglerminal_layer_scale(lua_State* L)
{ {
const unsigned char layer = luaL_checkinteger(L, 1) - 1; const unsigned char x = luaL_checkinteger(L, 1) - 1;
const float scale = luaL_checknumber(L, 2); const unsigned char y = luaL_checkinteger(L, 2) - 1;
glerminal_layer_scale(layer, scale); const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const float scale = luaL_checknumber(L, 4);
glerminal_scale(x, y, layer, scale);
return 0; return 0;
} }
@ -110,14 +114,11 @@ namespace
int message_handler(lua_State* L) int message_handler(lua_State* L)
{ {
const char* error_message = lua_tostring(L, -1); luaL_traceback(L, L, lua_tostring(L, -1), 1);
luaL_traceback(L, L, error_message, 1);
const char* err = lua_tostring(L, -1);
lua_remove(L, -2); lua_remove(L, -2);
glerminal_quit();
return true; return true;
} }

View File

@ -44,8 +44,8 @@ namespace glerminal
void set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite); void set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite);
unsigned short get(unsigned char x, unsigned char y, unsigned char layer) const; unsigned short get(unsigned char x, unsigned char y, unsigned char layer) const;
void offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset); void offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset);
void layer_color(unsigned char layer, unsigned int color); void color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color);
void layer_scale(unsigned char layer, float scale); void scale(unsigned char x, unsigned char y, unsigned char layer, float scale);
void load_atlas(unsigned char w, unsigned char h, const unsigned int* data); void load_atlas(unsigned char w, unsigned char h, const unsigned int* data);
private: private:
@ -67,8 +67,8 @@ namespace glerminal
unsigned int m_framebuffer_backing_texture; unsigned int m_framebuffer_backing_texture;
unsigned int m_screen_framebuffer; unsigned int m_screen_framebuffer;
unsigned int m_screen_framebuffer_backing_texture; unsigned int m_screen_framebuffer_backing_texture;
unsigned int m_layer_colors_buffer; unsigned int m_colors_instance_vbo;
unsigned int m_layer_scales_buffer; unsigned int m_scales_instance_vbo;
unsigned int m_screen_size_uniform_location; unsigned int m_screen_size_uniform_location;
unsigned int m_palette_uniform_location; unsigned int m_palette_uniform_location;
@ -76,11 +76,8 @@ namespace glerminal
unsigned short m_cells[GRID_AREA * LAYER_COUNT]; unsigned short m_cells[GRID_AREA * LAYER_COUNT];
float m_offsets[GRID_AREA * LAYER_COUNT * 2]; float m_offsets[GRID_AREA * LAYER_COUNT * 2];
unsigned char m_colors[GRID_AREA * LAYER_COUNT * 4];
// per-layer data float m_scales[GRID_AREA * LAYER_COUNT];
float m_layer_colors[LAYER_COUNT * 4];
float m_layer_scales[LAYER_COUNT];
// library state // library state
@ -100,8 +97,8 @@ namespace glerminal
void deinit_gl(); void deinit_gl();
void update_sprites(); void update_sprites();
void update_layer_colors(); void update_colors();
void update_layer_scales(); void update_scales();
static void glfw_key_handler(GLFWwindow* window, int key, int scancode, int action, int mods); static void glfw_key_handler(GLFWwindow* window, int key, int scancode, int action, int mods);
}; };

View File

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