This commit is contained in:
parent
e5b017ad97
commit
a39905c6cb
@ -9,6 +9,7 @@ extern "C"
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
#define WINDOWS_LEAN_AND_MEAN
|
||||||
@ -117,7 +118,7 @@ namespace
|
|||||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
// ignore error for now
|
||||||
lua_remove(L, -1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ namespace
|
|||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
// ignore error for now
|
||||||
lua_remove(L, -1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ namespace
|
|||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
// ignore error for now
|
||||||
lua_remove(L, -1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +164,7 @@ namespace
|
|||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
// ignore error for now
|
||||||
lua_remove(L, -1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,7 +190,11 @@ int main(int argc, char** argv)
|
|||||||
luaL_newlib(L, lglerminal_methods);
|
luaL_newlib(L, lglerminal_methods);
|
||||||
lua_setglobal(L, "glerminal");
|
lua_setglobal(L, "glerminal");
|
||||||
|
|
||||||
luaL_dofile(L, "main.lua");
|
if (luaL_dofile(L, "main.lua") != LUA_OK)
|
||||||
|
{
|
||||||
|
const char* str = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
glerminal_run(init, mainloop, pressed, released);
|
glerminal_run(init, mainloop, pressed, released);
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
namespace glerminal
|
namespace glerminal
|
||||||
{
|
{
|
||||||
constexpr unsigned int CELL_SIZE = 8;
|
constexpr unsigned int CELL_SIZE = 8;
|
||||||
|
constexpr unsigned int MAX_SPRITES_ROW = 64;
|
||||||
|
constexpr unsigned int MAX_SPRITES = MAX_SPRITES_ROW * MAX_SPRITES_ROW;
|
||||||
constexpr unsigned int GRID_WIDTH = ::GRID_WIDTH;
|
constexpr unsigned int GRID_WIDTH = ::GRID_WIDTH;
|
||||||
constexpr unsigned int GRID_HEIGHT = ::GRID_HEIGHT;
|
constexpr unsigned int GRID_HEIGHT = ::GRID_HEIGHT;
|
||||||
constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT;
|
constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT;
|
||||||
@ -72,7 +74,7 @@ namespace glerminal
|
|||||||
|
|
||||||
// per-cell data
|
// per-cell data
|
||||||
|
|
||||||
unsigned char 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];
|
||||||
|
|
||||||
// per-layer data
|
// per-layer data
|
||||||
@ -82,7 +84,7 @@ namespace glerminal
|
|||||||
|
|
||||||
// library state
|
// library state
|
||||||
|
|
||||||
unsigned int m_sprites[CELL_SIZE * CELL_SIZE * (1 << (8 * sizeof(*m_cells)))];
|
unsigned int m_sprites[CELL_SIZE * CELL_SIZE * MAX_SPRITES];
|
||||||
glerminal_main_cb m_main;
|
glerminal_main_cb m_main;
|
||||||
glerminal_keys_cb m_pressed, m_released;
|
glerminal_keys_cb m_pressed, m_released;
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#define STBI_ONLY_PNG
|
#define STBI_ONLY_PNG
|
||||||
#define STBI_MAX_DIMENSIONS 128
|
#define STBI_MAX_DIMENSIONS 512
|
||||||
#include "glerminal-private.h"
|
#include "glerminal-private.h"
|
||||||
|
|
||||||
#define GRID_SIZE_UNIFORM_NAME "grid_size"
|
#define GRID_SIZE_UNIFORM_NAME "grid_size"
|
||||||
#define SPRITES_UNIFORM_NAME "sprites"
|
#define SPRITES_UNIFORM_NAME "sprites"
|
||||||
#define LAYERS_UNIFORM_NAME "layers"
|
#define LAYERS_UNIFORM_NAME "layers"
|
||||||
#define LAYER_COUNT_UNIFORM_NAME "layer_count"
|
#define LAYER_COUNT_UNIFORM_NAME "layer_count"
|
||||||
|
#define ATLAS_WIDTH_UNIFORM_NAME "atlas_width"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -31,6 +32,7 @@ namespace
|
|||||||
"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"
|
||||||
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
||||||
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
||||||
"layout (std430, binding = 0) buffer LayerScales"
|
"layout (std430, binding = 0) buffer LayerScales"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float scales[];\n"
|
" float scales[];\n"
|
||||||
@ -52,7 +54,7 @@ namespace
|
|||||||
" 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 = lcs.colors[layer];\n"
|
||||||
" vs_out.texcoord = vec2(position.x + 1, -position.y);\n"
|
" vs_out.texcoord = (vec2((sprite + int(position.x + 1)) % " ATLAS_WIDTH_UNIFORM_NAME ", (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) + vec2((position.x + 0.5) / -16, (position.y + 0.5) / 16)) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ");\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(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"
|
" 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"
|
" gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n"
|
||||||
@ -67,6 +69,7 @@ namespace
|
|||||||
"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"
|
||||||
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
||||||
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
||||||
"layout (std430, binding = 0) buffer LayerScales"
|
"layout (std430, binding = 0) buffer LayerScales"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float scales[];\n"
|
" float scales[];\n"
|
||||||
@ -86,7 +89,7 @@ namespace
|
|||||||
" gl_Layer = layer;\n"
|
" gl_Layer = layer;\n"
|
||||||
" 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(position.x + 1, -position.y);\n"
|
" vs_out.texcoord = (vec2((sprite + int(position.x + 1)) % " ATLAS_WIDTH_UNIFORM_NAME ", (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) + vec2((position.x + 0.5) / -16, (position.y + 0.5) / 16)) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ");\n"
|
||||||
" vs_out.layer_color = lcs.colors[layer];\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 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"
|
" 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"
|
||||||
@ -139,11 +142,11 @@ namespace
|
|||||||
"flat in int sprite;\n"
|
"flat in int sprite;\n"
|
||||||
"flat vec4 layer_color;\n"
|
"flat vec4 layer_color;\n"
|
||||||
"in vec2 texcoord;\n"
|
"in vec2 texcoord;\n"
|
||||||
"layout (binding = 0) uniform sampler2DArray " SPRITES_UNIFORM_NAME ";\n"
|
"layout (binding = 2) uniform sampler2D " SPRITES_UNIFORM_NAME ";\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" FragColor = layer_color * texture(" SPRITES_UNIFORM_NAME ", vec3(texcoord, sprite));\n"
|
" FragColor = layer_color * texture(" SPRITES_UNIFORM_NAME ", texcoord);\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
// note: AMD_vertex_shader_layer support required
|
// note: AMD_vertex_shader_layer support required
|
||||||
@ -154,11 +157,11 @@ namespace
|
|||||||
" flat vec4 layer_color;\n"
|
" flat vec4 layer_color;\n"
|
||||||
" vec2 texcoord;\n"
|
" vec2 texcoord;\n"
|
||||||
"} fs_in;\n"
|
"} fs_in;\n"
|
||||||
"layout (binding = 0) uniform sampler2DArray " SPRITES_UNIFORM_NAME ";\n"
|
"layout (binding = 2) uniform sampler2D " SPRITES_UNIFORM_NAME ";\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" FragColor = fs_in.layer_color * texture(" SPRITES_UNIFORM_NAME ", vec3(fs_in.texcoord, fs_in.sprite));\n"
|
" FragColor = fs_in.layer_color * texture(" SPRITES_UNIFORM_NAME ", fs_in.texcoord);\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
constexpr const char* FRAGMENT_SHADER_SOURCE_PTR = FRAGMENT_SHADER_SOURCE;
|
constexpr const char* FRAGMENT_SHADER_SOURCE_PTR = FRAGMENT_SHADER_SOURCE;
|
||||||
@ -261,8 +264,6 @@ namespace glerminal
|
|||||||
m_main(current - last);
|
m_main(current - last);
|
||||||
|
|
||||||
last = current;
|
last = current;
|
||||||
|
|
||||||
glfwSwapBuffers(m_window);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +296,9 @@ namespace glerminal
|
|||||||
|
|
||||||
glfwSwapBuffers(m_window);
|
glfwSwapBuffers(m_window);
|
||||||
|
|
||||||
glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
//glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
|
//glfwSwapBuffers(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal::set(unsigned char x, unsigned char y, unsigned char layer, unsigned char sprite)
|
void glerminal::set(unsigned char x, unsigned char y, unsigned char layer, unsigned char sprite)
|
||||||
@ -351,10 +354,10 @@ namespace glerminal
|
|||||||
// each row of the individual sprite
|
// each row of the individual sprite
|
||||||
for (int k = 0; k < CELL_SIZE; k++)
|
for (int k = 0; k < CELL_SIZE; k++)
|
||||||
{
|
{
|
||||||
// offset from base address in atlas layout
|
// offset from base address in source atlas layout
|
||||||
const unsigned int src_offset = i + k * w + j * w * CELL_SIZE;
|
const unsigned int src_offset = i + k * w + j * w * CELL_SIZE;
|
||||||
// offset from base address in array layout
|
// offset from base address in glerminal atlas layout
|
||||||
const unsigned int dst_offset = k + i * CELL_SIZE + j * w * CELL_SIZE;
|
const unsigned int dst_offset = i + k * MAX_SPRITES_ROW + j * MAX_SPRITES_ROW * CELL_SIZE;
|
||||||
|
|
||||||
memcpy(m_sprites + CELL_SIZE * dst_offset, data + CELL_SIZE * src_offset, CELL_SIZE * sizeof(unsigned int));
|
memcpy(m_sprites + CELL_SIZE * dst_offset, data + CELL_SIZE * src_offset, CELL_SIZE * sizeof(unsigned int));
|
||||||
}
|
}
|
||||||
@ -499,7 +502,7 @@ namespace glerminal
|
|||||||
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);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glVertexAttribIPointer(2, 1, GL_UNSIGNED_BYTE, 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);
|
||||||
|
|
||||||
// set up static vertex attributes
|
// set up static vertex attributes
|
||||||
@ -617,6 +620,7 @@ namespace glerminal
|
|||||||
|
|
||||||
glUseProgram(m_program);
|
glUseProgram(m_program);
|
||||||
glUniform4f(m_screen_size_uniform_location, GRID_WIDTH, GRID_AREA, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
glUniform4f(m_screen_size_uniform_location, GRID_WIDTH, GRID_AREA, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
||||||
|
glUniform1i(glGetUniformLocation(m_program, ATLAS_WIDTH_UNIFORM_NAME), MAX_SPRITES_ROW);
|
||||||
|
|
||||||
// compile
|
// compile
|
||||||
const unsigned int screen_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
const unsigned int screen_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
@ -680,20 +684,23 @@ namespace glerminal
|
|||||||
|
|
||||||
// -- setup textures --
|
// -- setup textures --
|
||||||
glGenTextures(1, &m_sprites_texture);
|
glGenTextures(1, &m_sprites_texture);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
|
glBindTexture(GL_TEXTURE_2D, m_sprites_texture);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
|
||||||
|
glTextureStorage2D(m_sprites_texture, 1, GL_RGBA8, MAX_SPRITES_ROW * CELL_SIZE, MAX_SPRITES_ROW * CELL_SIZE);
|
||||||
|
|
||||||
update_sprites();
|
update_sprites();
|
||||||
|
|
||||||
glBindTextureUnit(0, m_sprites_texture);
|
glBindTextureUnit(2, m_sprites_texture);
|
||||||
|
const auto err = glGetError();
|
||||||
|
|
||||||
// -- setup framebuffer --
|
// -- setup framebuffer --
|
||||||
glGenFramebuffers(1, &m_framebuffer);
|
glGenFramebuffers(1, &m_framebuffer);
|
||||||
@ -762,8 +769,7 @@ namespace glerminal
|
|||||||
|
|
||||||
void glerminal::update_sprites()
|
void glerminal::update_sprites()
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
|
glTextureSubImage2D(m_sprites_texture, 0, 0, 0, CELL_SIZE * MAX_SPRITES_ROW, CELL_SIZE * MAX_SPRITES_ROW, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites);
|
||||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, CELL_SIZE, CELL_SIZE, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal::update_layer_colors()
|
void glerminal::update_layer_colors()
|
||||||
|
Loading…
Reference in New Issue
Block a user