diff --git a/source/glerminal-main.cpp b/source/glerminal-main.cpp index 2d653d0..ed4ba79 100644 --- a/source/glerminal-main.cpp +++ b/source/glerminal-main.cpp @@ -9,6 +9,7 @@ extern "C" } #include +#include #ifdef _WIN32 #define WINDOWS_LEAN_AND_MEAN @@ -117,7 +118,7 @@ namespace if (lua_pcall(L, 0, 0, 0) != LUA_OK) { // 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) { // 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) { // 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) { // 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); 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); diff --git a/source/glerminal-private.h b/source/glerminal-private.h index ae29ac8..088c382 100644 --- a/source/glerminal-private.h +++ b/source/glerminal-private.h @@ -14,6 +14,8 @@ namespace glerminal { 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_HEIGHT = ::GRID_HEIGHT; constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT; @@ -72,7 +74,7 @@ namespace glerminal // 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]; // per-layer data @@ -82,7 +84,7 @@ namespace glerminal // 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_keys_cb m_pressed, m_released; diff --git a/source/glerminal.cpp b/source/glerminal.cpp index a07e170..4fd64e3 100644 --- a/source/glerminal.cpp +++ b/source/glerminal.cpp @@ -1,12 +1,13 @@ #define STB_IMAGE_IMPLEMENTATION #define STBI_ONLY_PNG -#define STBI_MAX_DIMENSIONS 128 +#define STBI_MAX_DIMENSIONS 512 #include "glerminal-private.h" #define GRID_SIZE_UNIFORM_NAME "grid_size" #define SPRITES_UNIFORM_NAME "sprites" #define LAYERS_UNIFORM_NAME "layers" #define LAYER_COUNT_UNIFORM_NAME "layer_count" +#define ATLAS_WIDTH_UNIFORM_NAME "atlas_width" namespace { @@ -31,6 +32,7 @@ namespace "layout (location = 1) in vec2 offset;\n" "layout (location = 2) in int sprite;\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" @@ -52,7 +54,7 @@ namespace " vs_out.sprite = sprite;\n" " vs_out.layer = 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 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" @@ -67,6 +69,7 @@ namespace "layout (location = 1) in vec2 offset;\n" "layout (location = 2) in int sprite;\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" @@ -86,7 +89,7 @@ namespace " gl_Layer = layer;\n" " vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\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" " 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" @@ -139,11 +142,11 @@ namespace "flat in int sprite;\n" "flat vec4 layer_color;\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" "void main()\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 @@ -154,11 +157,11 @@ namespace " flat vec4 layer_color;\n" " vec2 texcoord;\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" "void main()\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; @@ -261,8 +264,6 @@ namespace glerminal m_main(current - last); last = current; - - glfwSwapBuffers(m_window); } } @@ -295,7 +296,9 @@ namespace glerminal 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) @@ -351,10 +354,10 @@ namespace glerminal // each row of the individual sprite 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; - // offset from base address in array layout - const unsigned int dst_offset = k + i * CELL_SIZE + j * w * CELL_SIZE; + // offset from base address in glerminal atlas layout + 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)); } @@ -499,7 +502,7 @@ namespace glerminal glBindBuffer(GL_ARRAY_BUFFER, m_sprites_instance_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(m_cells), m_cells, GL_STREAM_DRAW); glEnableVertexAttribArray(2); - glVertexAttribIPointer(2, 1, GL_UNSIGNED_BYTE, 1 * sizeof(*m_cells), reinterpret_cast(0)); + glVertexAttribIPointer(2, 1, GL_UNSIGNED_SHORT, 1 * sizeof(*m_cells), reinterpret_cast(0)); glVertexAttribDivisor(2, 1); // set up static vertex attributes @@ -617,6 +620,7 @@ namespace glerminal glUseProgram(m_program); 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 const unsigned int screen_vertex_shader = glCreateShader(GL_VERTEX_SHADER); @@ -680,20 +684,23 @@ namespace glerminal // -- setup textures -- 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_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_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(); - glBindTextureUnit(0, m_sprites_texture); + glBindTextureUnit(2, m_sprites_texture); + const auto err = glGetError(); // -- setup framebuffer -- glGenFramebuffers(1, &m_framebuffer); @@ -762,8 +769,7 @@ namespace glerminal void glerminal::update_sprites() { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, CELL_SIZE, CELL_SIZE, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites); + glTextureSubImage2D(m_sprites_texture, 0, 0, 0, CELL_SIZE * MAX_SPRITES_ROW, CELL_SIZE * MAX_SPRITES_ROW, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites); } void glerminal::update_layer_colors()