mirror of
https://git.shylie.info/shylie/glerminal.git
synced 2024-11-21 16:40:04 +00:00
Properly fixed texture bleeding
This commit is contained in:
parent
71c052b38f
commit
da1f32a014
@ -35,7 +35,7 @@ void glerminal_flush();
|
|||||||
* @param layer layer of the cell in the range [0, 8)
|
* @param layer layer of the cell in the range [0, 8)
|
||||||
* @param sprite sprite's index in the range [0, 256)
|
* @param sprite sprite's index in the range [0, 256)
|
||||||
*/
|
*/
|
||||||
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 short sprite);
|
||||||
/**
|
/**
|
||||||
* @brief Get a cell's sprite
|
* @brief Get a cell's sprite
|
||||||
* @param x position of the cell in the range [0, 40)
|
* @param x position of the cell in the range [0, 40)
|
||||||
@ -43,7 +43,7 @@ void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsign
|
|||||||
* @param layer layer of the cell in the range [0, 8)
|
* @param layer layer of the cell in the range [0, 8)
|
||||||
* @return sprite index currently assigned to the cell
|
* @return sprite index currently assigned to the cell
|
||||||
*/
|
*/
|
||||||
unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char layer);
|
unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned short layer);
|
||||||
/**
|
/**
|
||||||
* @brief Set a cell's offset
|
* @brief Set a cell's offset
|
||||||
* @param x position of the cell in the range [0, 40)
|
* @param x position of the cell in the range [0, 40)
|
||||||
|
@ -41,7 +41,7 @@ namespace
|
|||||||
const unsigned char x = luaL_checkinteger(L, 1) - 1;
|
const unsigned char x = luaL_checkinteger(L, 1) - 1;
|
||||||
const unsigned char y = luaL_checkinteger(L, 2) - 1;
|
const unsigned char y = luaL_checkinteger(L, 2) - 1;
|
||||||
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
|
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
|
||||||
const unsigned char sprite = luaL_checkinteger(L, 4) - 1;
|
const unsigned short sprite = luaL_checkinteger(L, 4) - 1;
|
||||||
glerminal_set(x, y, layer, sprite);
|
glerminal_set(x, y, layer, sprite);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -108,31 +108,50 @@ namespace
|
|||||||
{ nullptr, nullptr }
|
{ nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int message_handler(lua_State* L)
|
||||||
|
{
|
||||||
|
const char* error_message = lua_tostring(L, -1);
|
||||||
|
|
||||||
|
luaL_traceback(L, L, error_message, 0);
|
||||||
|
|
||||||
|
const char* err = lua_tostring(L, -1);
|
||||||
|
|
||||||
|
lua_remove(L, -2);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
lua_State* L;
|
lua_State* L;
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
|
lua_pushcfunction(L, message_handler);
|
||||||
|
const int handler = lua_gettop(L);
|
||||||
lua_getglobal(L, "glerminal");
|
lua_getglobal(L, "glerminal");
|
||||||
lua_getfield(L, -1, "init");
|
lua_getfield(L, -1, "init");
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 0, 0, handler) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
std::cout << lua_tostring(L, -1) << std::endl;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
lua_remove(L, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mainloop(float dt)
|
void mainloop(float dt)
|
||||||
{
|
{
|
||||||
|
lua_pushcfunction(L, message_handler);
|
||||||
|
const int handler = lua_gettop(L);
|
||||||
lua_getglobal(L, "glerminal");
|
lua_getglobal(L, "glerminal");
|
||||||
lua_getfield(L, -1, "main");
|
lua_getfield(L, -1, "main");
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
lua_pushnumber(L, dt);
|
lua_pushnumber(L, dt);
|
||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
std::cout << lua_tostring(L, -1) << std::endl;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
lua_remove(L, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pressed(int key)
|
void pressed(int key)
|
||||||
@ -140,15 +159,18 @@ namespace
|
|||||||
const char* const name = glfwGetKeyName(key, 0);
|
const char* const name = glfwGetKeyName(key, 0);
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
|
lua_pushcfunction(L, message_handler);
|
||||||
|
const int handler = lua_gettop(L);
|
||||||
lua_getglobal(L, "glerminal");
|
lua_getglobal(L, "glerminal");
|
||||||
lua_getfield(L, -1, "pressed");
|
lua_getfield(L, -1, "pressed");
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
std::cout << lua_tostring(L, -1) << std::endl;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
lua_remove(L, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,15 +179,18 @@ namespace
|
|||||||
const char* const name = glfwGetKeyName(key, 0);
|
const char* const name = glfwGetKeyName(key, 0);
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
|
lua_pushcfunction(L, message_handler);
|
||||||
|
const int handler = lua_gettop(L);
|
||||||
lua_getglobal(L, "glerminal");
|
lua_getglobal(L, "glerminal");
|
||||||
lua_getfield(L, -1, "released");
|
lua_getfield(L, -1, "released");
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
||||||
{
|
{
|
||||||
// ignore error for now
|
std::cout << lua_tostring(L, -1) << std::endl;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
lua_remove(L, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,8 @@ namespace glerminal
|
|||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
void set(unsigned char x, unsigned char y, unsigned char layer, unsigned char sprite);
|
void set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite);
|
||||||
unsigned char 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 layer_color(unsigned char layer, unsigned int color);
|
||||||
void layer_scale(unsigned char layer, float scale);
|
void layer_scale(unsigned char layer, float scale);
|
||||||
@ -84,7 +84,7 @@ namespace glerminal
|
|||||||
|
|
||||||
// library state
|
// library state
|
||||||
|
|
||||||
unsigned int m_sprites[CELL_SIZE * CELL_SIZE * MAX_SPRITES];
|
unsigned int m_sprites[(CELL_SIZE + 2) * (CELL_SIZE + 2) * 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;
|
||||||
|
|
||||||
|
@ -54,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((sprite + int(position.x + 1)) % " ATLAS_WIDTH_UNIFORM_NAME ", (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) + vec2((position.x + 0.5) / -32, (position.y + 0.5) / 32)) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ");\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(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"
|
||||||
@ -89,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((sprite + int(position.x + 1)) % " ATLAS_WIDTH_UNIFORM_NAME ", (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) + vec2((position.x + 0.5) / -32, (position.y + 0.5) / 32)) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ");\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 = 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"
|
||||||
@ -294,10 +294,13 @@ namespace glerminal
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
glfwSwapInterval(0);
|
||||||
|
glfwSwapBuffers(m_window);
|
||||||
|
glfwSwapInterval(1);
|
||||||
glfwSwapBuffers(m_window);
|
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 short sprite)
|
||||||
{
|
{
|
||||||
if (x < GRID_WIDTH && y < GRID_HEIGHT && layer < LAYER_COUNT)
|
if (x < GRID_WIDTH && y < GRID_HEIGHT && layer < LAYER_COUNT)
|
||||||
{
|
{
|
||||||
@ -305,7 +308,7 @@ namespace glerminal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char glerminal::get(unsigned char x, unsigned char y, unsigned char layer) const
|
unsigned short glerminal::get(unsigned char x, unsigned char y, unsigned char layer) const
|
||||||
{
|
{
|
||||||
if (x < GRID_WIDTH && y < GRID_HEIGHT && layer < LAYER_COUNT)
|
if (x < GRID_WIDTH && y < GRID_HEIGHT && layer < LAYER_COUNT)
|
||||||
{
|
{
|
||||||
@ -341,21 +344,25 @@ namespace glerminal
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
// each row of the atlas
|
for (int src_atlas_row = 0; src_atlas_row < h; src_atlas_row++)
|
||||||
for (int j = 0; j < h; j++)
|
|
||||||
{
|
{
|
||||||
// each column of the atlas
|
for (int src_atlas_col = 0; src_atlas_col < w; src_atlas_col++)
|
||||||
for (int i = 0; i < w; i++)
|
|
||||||
{
|
{
|
||||||
// each row of the individual sprite
|
for (int sprite_row = 0; sprite_row < CELL_SIZE; sprite_row++)
|
||||||
for (int k = 0; k < CELL_SIZE; k++)
|
|
||||||
{
|
{
|
||||||
// offset from base address in source atlas layout
|
const unsigned int sprite_index = src_atlas_col + src_atlas_row * w;
|
||||||
const unsigned int src_offset = i + k * w + j * w * CELL_SIZE;
|
const unsigned int dst_atlas_row = sprite_index / MAX_SPRITES_ROW;
|
||||||
// offset from base address in glerminal atlas layout
|
const unsigned int dst_atlas_col = sprite_index % MAX_SPRITES_ROW;
|
||||||
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));
|
// offset from base address in source atlas layout
|
||||||
|
const unsigned int src_offset = CELL_SIZE * (src_atlas_col + sprite_row * w + src_atlas_row * w * CELL_SIZE);
|
||||||
|
|
||||||
|
const unsigned int dst_column = dst_atlas_col * (CELL_SIZE + 2) + 1;
|
||||||
|
const unsigned int dst_row = MAX_SPRITES_ROW * (CELL_SIZE + 2) * ((sprite_row + 1) + dst_atlas_row * (CELL_SIZE + 2));
|
||||||
|
// offset from base address in glerminal atlas layout
|
||||||
|
const unsigned int dst_offset = dst_column + dst_row;
|
||||||
|
|
||||||
|
memcpy(m_sprites + dst_offset, data + src_offset, CELL_SIZE * sizeof(unsigned int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,7 +372,6 @@ namespace glerminal
|
|||||||
{
|
{
|
||||||
glfwInit();
|
glfwInit();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
@ -691,7 +697,7 @@ namespace glerminal
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, 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);
|
glTextureStorage2D(m_sprites_texture, 1, GL_RGBA8, MAX_SPRITES_ROW * (CELL_SIZE + 2), MAX_SPRITES_ROW * (CELL_SIZE + 2));
|
||||||
|
|
||||||
update_sprites();
|
update_sprites();
|
||||||
|
|
||||||
@ -765,7 +771,7 @@ namespace glerminal
|
|||||||
|
|
||||||
void glerminal::update_sprites()
|
void glerminal::update_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);
|
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_layer_colors()
|
||||||
@ -822,14 +828,14 @@ void glerminal_flush()
|
|||||||
GLERMINAL_G->flush();
|
GLERMINAL_G->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 short sprite)
|
||||||
{
|
{
|
||||||
if (!GLERMINAL_G) { return; }
|
if (!GLERMINAL_G) { return; }
|
||||||
|
|
||||||
GLERMINAL_G->set(x, y, layer, sprite);
|
GLERMINAL_G->set(x, y, layer, sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char layer)
|
unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned short layer)
|
||||||
{
|
{
|
||||||
if (!GLERMINAL_G) { return 0; }
|
if (!GLERMINAL_G) { return 0; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user