mirror of
https://git.shylie.info/shylie/glerminal.git
synced 2024-12-22 06:30:05 +00:00
Allow for up to 4096 sprites
This commit is contained in:
parent
e5b017ad97
commit
a39905c6cb
@ -9,6 +9,7 @@ extern "C"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<void*>(0));
|
||||
glVertexAttribIPointer(2, 1, GL_UNSIGNED_SHORT, 1 * sizeof(*m_cells), reinterpret_cast<void*>(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()
|
||||
|
Loading…
Reference in New Issue
Block a user