Per-layer tinting and scaling
This commit is contained in:
parent
325ef5167d
commit
e3a65072d8
@ -6,15 +6,15 @@ namespace
|
|||||||
{
|
{
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
glerminal_update_sprite(0xFF00007F, {
|
glerminal_update_sprite(1, {
|
||||||
0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F,
|
0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0xFF00007F, 0x00FF007F,
|
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
||||||
0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F, 0x00FF007F
|
0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,10 +37,10 @@ namespace
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < 25; j++)
|
for (int j = 0; j < 25; j++)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < 8; k++)
|
for (int k = 0; k < 256; k++)
|
||||||
{
|
{
|
||||||
glerminal_set(i, j, k, rand() % 2);
|
glerminal_set(i, j, k, rand() % 8 == 0);
|
||||||
glerminal_offset(i, j, k, (rand() * rand()) % 100 - 50, (rand() * rand()) % 100 - 50);
|
glerminal_offset(i, j, k, (rand() * rand()) % 64 - 32, (rand() * rand()) % 64 - 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,34 +7,25 @@ namespace
|
|||||||
{
|
{
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
for (int i = 1; i < 256; i++)
|
glerminal_update_sprite(1,
|
||||||
{
|
|
||||||
constexpr unsigned char c = 16;
|
|
||||||
const unsigned char v = (255 - c) * powf((i - 1) / 256.0f, 4.0f) + c;
|
|
||||||
const unsigned int j = (0xFF << 24) | (v << 16) | (v << 8) | v;
|
|
||||||
glerminal_update_sprite(i,
|
|
||||||
{
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
j,j,j,j,j,j,j,j,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 40; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 25; j++)
|
|
||||||
{
|
{
|
||||||
const int c = rand() % 224 + 32;
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
for (int k = 0; k < c; k++)
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
{
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
glerminal_set(i, j, k, k);
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
}
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
}
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
|
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
constexpr unsigned char c = 32;
|
||||||
|
const unsigned char v = (255 - c) * powf((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 / 256.0f + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +35,7 @@ namespace
|
|||||||
|
|
||||||
time += dt;
|
time += dt;
|
||||||
|
|
||||||
if (time < 1.0f)
|
if (time < 0.15f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -60,11 +51,20 @@ namespace
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < 25; j++)
|
for (int j = 0; j < 25; j++)
|
||||||
{
|
{
|
||||||
|
const int c = rand() % 224 + 32;
|
||||||
for (int k = 0; k < 256; k++)
|
for (int k = 0; k < 256; k++)
|
||||||
{
|
{
|
||||||
const float ox = 0.025f * powf(k, 0.8f) * (i - cx);
|
if (k < c)
|
||||||
const float oy = 0.025f * powf(k, 0.8f) * (j - cy);
|
{
|
||||||
glerminal_offset(i, j, k, ox, oy);
|
glerminal_set(i, j, k, 1);
|
||||||
|
const float ox = 0.01f * k * (i - cx);
|
||||||
|
const float oy = 0.01f * k * (j - cy);
|
||||||
|
glerminal_offset(i, j, k, ox + (1 + 0.004f * k) * cosf(c * i + k * 6.28f / 128.0f), oy + (1 + 0.004f * k) * sinf(c * j + k * 6.28f / 128.0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glerminal_set(i, j, k, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,19 @@ unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char laye
|
|||||||
*/
|
*/
|
||||||
void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset);
|
void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set a layer's color
|
||||||
|
* @param layer The layer to modify
|
||||||
|
* @param color The new color
|
||||||
|
*/
|
||||||
|
void glerminal_layer_color(unsigned char layer, unsigned int color);
|
||||||
|
/**
|
||||||
|
* @brief Set a layer's scale
|
||||||
|
* @param layer The layer to modify
|
||||||
|
* @param scale The new scale
|
||||||
|
*/
|
||||||
|
void glerminal_layer_scale(unsigned char layer, float scale);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Upload sprite to the given sprite ID
|
* @brief Upload sprite to the given sprite ID
|
||||||
* @param id The ID of the sprite to change
|
* @param id The ID of the sprite to change
|
||||||
|
@ -41,30 +41,46 @@ namespace glerminal
|
|||||||
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 char sprite);
|
||||||
unsigned char get(unsigned char x, unsigned char y, unsigned char layer) const;
|
unsigned char 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_scale(unsigned char layer, float scale);
|
||||||
|
|
||||||
void update_sprite(unsigned char id, glerminal_sprite sprite);
|
void update_sprite(unsigned char id, glerminal_sprite sprite);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// glfw data
|
||||||
|
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window;
|
||||||
|
|
||||||
|
// opengl handles
|
||||||
|
|
||||||
unsigned int m_vbo;
|
unsigned int m_vbo;
|
||||||
unsigned int m_sprites_instance_vbo;
|
unsigned int m_sprites_instance_vbo;
|
||||||
unsigned int m_offsets_instance_vbo;
|
unsigned int m_offsets_instance_vbo;
|
||||||
unsigned int m_vao;
|
unsigned int m_vao;
|
||||||
unsigned int m_program;
|
|
||||||
unsigned int m_screen_vao;
|
unsigned int m_screen_vao;
|
||||||
|
unsigned int m_program;
|
||||||
unsigned int m_screen_program;
|
unsigned int m_screen_program;
|
||||||
unsigned int m_sprites_texture;
|
unsigned int m_sprites_texture;
|
||||||
unsigned int m_framebuffer;
|
unsigned int m_framebuffer;
|
||||||
unsigned int m_framebuffer_backing_texture;
|
unsigned int m_framebuffer_backing_texture;
|
||||||
|
unsigned int m_layer_colors_buffer;
|
||||||
|
unsigned int m_layer_scales_buffer;
|
||||||
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;
|
||||||
|
|
||||||
|
// per-cell data
|
||||||
|
|
||||||
unsigned char m_cells[GRID_AREA * LAYER_COUNT];
|
unsigned char m_cells[GRID_AREA * LAYER_COUNT];
|
||||||
float m_offsets[GRID_AREA * LAYER_COUNT * 2];
|
float m_offsets[GRID_AREA * LAYER_COUNT * 2];
|
||||||
|
|
||||||
unsigned int m_sprites[CELL_SIZE * CELL_SIZE * 256];
|
// per-layer data
|
||||||
|
|
||||||
|
float m_layer_colors[LAYER_COUNT * 4];
|
||||||
|
float m_layer_scales[LAYER_COUNT];
|
||||||
|
|
||||||
|
// library state
|
||||||
|
|
||||||
|
unsigned int m_sprites[CELL_SIZE * CELL_SIZE * (1 << (8 * sizeof(*m_cells)))];
|
||||||
glerminal_main_cb m_main;
|
glerminal_main_cb m_main;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -79,6 +95,8 @@ namespace glerminal
|
|||||||
void deinit_gl();
|
void deinit_gl();
|
||||||
|
|
||||||
void update_sprites();
|
void update_sprites();
|
||||||
|
void update_layer_colors();
|
||||||
|
void update_layer_scales();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr char* VERTEX_SHADER_SOURCE =
|
constexpr char* VERTEX_SHADER_SOURCE =
|
||||||
"#version 400 core\n"
|
"#version 460 core\n"
|
||||||
"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"
|
||||||
@ -45,7 +45,7 @@ namespace
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
constexpr char* GEOMETRY_SHADER_SOURCE =
|
constexpr char* GEOMETRY_SHADER_SOURCE =
|
||||||
"#version 400 core\n"
|
"#version 460 core\n"
|
||||||
"layout (triangles) in;\n"
|
"layout (triangles) in;\n"
|
||||||
"layout (triangle_strip, max_vertices = 3) out;\n"
|
"layout (triangle_strip, max_vertices = 3) out;\n"
|
||||||
"in VS_OUT {\n"
|
"in VS_OUT {\n"
|
||||||
@ -55,21 +55,25 @@ namespace
|
|||||||
" vec2 texcoord;\n"
|
" vec2 texcoord;\n"
|
||||||
"} gs_in[];\n"
|
"} gs_in[];\n"
|
||||||
"flat out int sprite;\n"
|
"flat out int sprite;\n"
|
||||||
|
"layout (std430, binding = 0) buffer LayerScales"
|
||||||
|
"{\n"
|
||||||
|
" float scales[];\n"
|
||||||
|
"} lss;\n"
|
||||||
"out vec2 texcoord;\n"
|
"out vec2 texcoord;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Layer = gs_in[0].layer;\n"
|
" gl_Layer = gs_in[0].layer;\n"
|
||||||
" gl_Position = vec4(gl_in[0].gl_Position.xy + gs_in[0].offset, 0, 1);\n"
|
" gl_Position = vec4(gl_in[0].gl_Position.xy * lss.scales[gs_in[0].layer] + gs_in[0].offset, 0, 1);\n"
|
||||||
" sprite = gs_in[0].sprite;\n"
|
" sprite = gs_in[0].sprite;\n"
|
||||||
" texcoord = gs_in[0].texcoord;\n"
|
" texcoord = gs_in[0].texcoord;\n"
|
||||||
" EmitVertex();\n"
|
" EmitVertex();\n"
|
||||||
" gl_Layer = gs_in[1].layer;\n"
|
" gl_Layer = gs_in[1].layer;\n"
|
||||||
" gl_Position = vec4(gl_in[1].gl_Position.xy + gs_in[1].offset, 0, 1);\n"
|
" gl_Position = vec4(gl_in[1].gl_Position.xy * lss.scales[gs_in[1].layer] + gs_in[1].offset, 0, 1);\n"
|
||||||
" sprite = gs_in[1].sprite;\n"
|
" sprite = gs_in[1].sprite;\n"
|
||||||
" texcoord = gs_in[1].texcoord;\n"
|
" texcoord = gs_in[1].texcoord;\n"
|
||||||
" EmitVertex();\n"
|
" EmitVertex();\n"
|
||||||
" gl_Layer = gs_in[2].layer;\n"
|
" gl_Layer = gs_in[2].layer;\n"
|
||||||
" gl_Position = vec4(gl_in[2].gl_Position.xy + gs_in[2].offset, 0, 1);\n"
|
" gl_Position = vec4(gl_in[2].gl_Position.xy * lss.scales[gs_in[2].layer] + gs_in[2].offset, 0, 1);\n"
|
||||||
" sprite = gs_in[2].sprite;\n"
|
" sprite = gs_in[2].sprite;\n"
|
||||||
" texcoord = gs_in[2].texcoord;\n"
|
" texcoord = gs_in[2].texcoord;\n"
|
||||||
" EmitVertex();\n"
|
" EmitVertex();\n"
|
||||||
@ -77,10 +81,10 @@ namespace
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
constexpr char* FRAGMENT_SHADER_SOURCE =
|
constexpr char* FRAGMENT_SHADER_SOURCE =
|
||||||
"#version 400 core\n"
|
"#version 460 core\n"
|
||||||
"in vec2 texcoord;\n"
|
"in vec2 texcoord;\n"
|
||||||
"flat in int sprite;\n"
|
"flat in int sprite;\n"
|
||||||
"uniform sampler2DArray " SPRITES_UNIFORM_NAME ";\n"
|
"layout (binding = 0) uniform sampler2DArray " SPRITES_UNIFORM_NAME ";\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
@ -88,7 +92,7 @@ namespace
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
constexpr char* SCREEN_VERTEX_SHADER_SOURCE =
|
constexpr char* SCREEN_VERTEX_SHADER_SOURCE =
|
||||||
"#version 400 core\n"
|
"#version 460 core\n"
|
||||||
"layout (location = 0) in vec2 position;\n"
|
"layout (location = 0) in vec2 position;\n"
|
||||||
"out vec2 texcoord;\n"
|
"out vec2 texcoord;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
@ -98,16 +102,20 @@ namespace
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
constexpr char* SCREEN_FRAGMENT_SHADER_SOURCE =
|
constexpr char* SCREEN_FRAGMENT_SHADER_SOURCE =
|
||||||
"#version 400 core\n"
|
"#version 460 core\n"
|
||||||
"in vec2 texcoord;\n"
|
"in vec2 texcoord;\n"
|
||||||
"uniform sampler2DArray " LAYERS_UNIFORM_NAME ";\n"
|
"layout (binding = 1) uniform sampler2DArray " LAYERS_UNIFORM_NAME ";\n"
|
||||||
|
"layout (std430, binding = 1) buffer LayerColors"
|
||||||
|
"{\n"
|
||||||
|
" vec4 colors[];\n"
|
||||||
|
"} lcs;\n"
|
||||||
"out vec4 FragColor;\n"
|
"out vec4 FragColor;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" vec3 current_color = vec3(0);\n"
|
" vec3 current_color = vec3(0);\n"
|
||||||
" for (int i = 0; i < 256; i++)\n"
|
" for (int i = 0; i < 256; i++)\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" vec4 texsample = texture(" LAYERS_UNIFORM_NAME ", vec3(texcoord, i));\n"
|
" vec4 texsample = lcs.colors[i] * texture(" LAYERS_UNIFORM_NAME ", vec3(texcoord, i));\n"
|
||||||
" current_color = mix(current_color, texsample.rgb, texsample.a);\n"
|
" current_color = mix(current_color, texsample.rgb, texsample.a);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" FragColor = vec4(current_color, 1);\n"
|
" FragColor = vec4(current_color, 1);\n"
|
||||||
@ -120,7 +128,9 @@ namespace glerminal
|
|||||||
m_main(main),
|
m_main(main),
|
||||||
m_cells{ },
|
m_cells{ },
|
||||||
m_offsets{ },
|
m_offsets{ },
|
||||||
m_sprites{ }
|
m_sprites{ },
|
||||||
|
m_layer_colors{ },
|
||||||
|
m_layer_scales{ }
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
, m_log("log.txt")
|
, m_log("log.txt")
|
||||||
#endif
|
#endif
|
||||||
@ -141,6 +151,12 @@ 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++)
|
||||||
|
{
|
||||||
|
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_layer_scales[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
init_glfw();
|
init_glfw();
|
||||||
init_gl();
|
init_gl();
|
||||||
|
|
||||||
@ -174,14 +190,14 @@ namespace glerminal
|
|||||||
|
|
||||||
void glerminal::flush()
|
void glerminal::flush()
|
||||||
{
|
{
|
||||||
// use dirty flag later
|
|
||||||
glNamedBufferData(m_sprites_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
|
glNamedBufferData(m_sprites_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
|
||||||
glNamedBufferData(m_offsets_instance_vbo, sizeof(m_offsets), m_offsets, GL_STREAM_DRAW);
|
glNamedBufferData(m_offsets_instance_vbo, sizeof(m_offsets), m_offsets, GL_STREAM_DRAW);
|
||||||
update_sprites();
|
update_sprites();
|
||||||
|
update_layer_colors();
|
||||||
|
update_layer_scales();
|
||||||
|
|
||||||
glViewport(0, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE);
|
glViewport(0, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE);
|
||||||
glUseProgram(m_program);
|
glUseProgram(m_program);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||||
glBindVertexArray(m_vao);
|
glBindVertexArray(m_vao);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
@ -189,7 +205,6 @@ namespace glerminal
|
|||||||
|
|
||||||
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
glUseProgram(m_screen_program);
|
glUseProgram(m_screen_program);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_framebuffer_backing_texture);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glBindVertexArray(m_screen_vao);
|
glBindVertexArray(m_screen_vao);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
@ -227,6 +242,19 @@ namespace glerminal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glerminal::layer_color(unsigned char layer, unsigned int color)
|
||||||
|
{
|
||||||
|
m_layer_colors[layer * 4 + 0] = ((color >> 0) & 0xFF) / 255.0f;
|
||||||
|
m_layer_colors[layer * 4 + 1] = ((color >> 8) & 0xFF) / 255.0f;
|
||||||
|
m_layer_colors[layer * 4 + 2] = ((color >> 16) & 0xFF) / 255.0f;
|
||||||
|
m_layer_colors[layer * 4 + 3] = ((color >> 24) & 0xFF) / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glerminal::layer_scale(unsigned char layer, float scale)
|
||||||
|
{
|
||||||
|
m_layer_scales[layer] = scale;
|
||||||
|
}
|
||||||
|
|
||||||
void glerminal::update_sprite(unsigned char id, glerminal_sprite sprite)
|
void glerminal::update_sprite(unsigned char id, glerminal_sprite sprite)
|
||||||
{
|
{
|
||||||
// does this work?
|
// does this work?
|
||||||
@ -342,6 +370,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_layer_scales_buffer);
|
||||||
|
|
||||||
// create vertex array object
|
// create vertex array object
|
||||||
glGenVertexArrays(1, &m_vao);
|
glGenVertexArrays(1, &m_vao);
|
||||||
@ -374,6 +404,16 @@ namespace glerminal
|
|||||||
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));
|
||||||
|
|
||||||
|
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 --
|
||||||
// compile
|
// compile
|
||||||
const unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
const unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
@ -388,12 +428,16 @@ namespace glerminal
|
|||||||
glShaderSource(fragment_shader, 1, &FRAGMENT_SHADER_SOURCE, nullptr);
|
glShaderSource(fragment_shader, 1, &FRAGMENT_SHADER_SOURCE, nullptr);
|
||||||
glCompileShader(fragment_shader);
|
glCompileShader(fragment_shader);
|
||||||
|
|
||||||
|
constexpr int INFO_LOG_SIZE = 512;
|
||||||
int success;
|
int success;
|
||||||
|
char info_log[INFO_LOG_SIZE];
|
||||||
|
|
||||||
// verify compile
|
// verify compile
|
||||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
glGetShaderInfoLog(vertex_shader, INFO_LOG_SIZE, nullptr, info_log);
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
glDeleteShader(vertex_shader);
|
||||||
glDeleteShader(geometry_shader);
|
glDeleteShader(geometry_shader);
|
||||||
glDeleteShader(fragment_shader);
|
glDeleteShader(fragment_shader);
|
||||||
@ -404,6 +448,8 @@ namespace glerminal
|
|||||||
glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &success);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
glGetShaderInfoLog(geometry_shader, INFO_LOG_SIZE, nullptr, info_log);
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
glDeleteShader(vertex_shader);
|
||||||
glDeleteShader(geometry_shader);
|
glDeleteShader(geometry_shader);
|
||||||
glDeleteShader(fragment_shader);
|
glDeleteShader(fragment_shader);
|
||||||
@ -414,6 +460,8 @@ namespace glerminal
|
|||||||
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
glGetShaderInfoLog(fragment_shader, INFO_LOG_SIZE, nullptr, info_log);
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
glDeleteShader(vertex_shader);
|
||||||
glDeleteShader(geometry_shader);
|
glDeleteShader(geometry_shader);
|
||||||
glDeleteShader(fragment_shader);
|
glDeleteShader(fragment_shader);
|
||||||
@ -446,8 +494,6 @@ namespace glerminal
|
|||||||
glUseProgram(m_program);
|
glUseProgram(m_program);
|
||||||
glUniform4f(m_screen_size_uniform_location, GRID_WIDTH, GRID_HEIGHT, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
glUniform4f(m_screen_size_uniform_location, GRID_WIDTH, GRID_HEIGHT, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
||||||
|
|
||||||
glUniform1i(glGetUniformLocation(m_program, SPRITES_UNIFORM_NAME), 0);
|
|
||||||
|
|
||||||
// compile
|
// compile
|
||||||
const unsigned int screen_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
const unsigned int screen_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(screen_vertex_shader, 1, &SCREEN_VERTEX_SHADER_SOURCE, nullptr);
|
glShaderSource(screen_vertex_shader, 1, &SCREEN_VERTEX_SHADER_SOURCE, nullptr);
|
||||||
@ -461,6 +507,8 @@ namespace glerminal
|
|||||||
glGetShaderiv(screen_vertex_shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(screen_vertex_shader, GL_COMPILE_STATUS, &success);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
glGetShaderInfoLog(screen_vertex_shader, INFO_LOG_SIZE, 0, info_log);
|
||||||
|
|
||||||
glDeleteShader(screen_vertex_shader);
|
glDeleteShader(screen_vertex_shader);
|
||||||
glDeleteShader(screen_fragment_shader);
|
glDeleteShader(screen_fragment_shader);
|
||||||
|
|
||||||
@ -470,6 +518,8 @@ namespace glerminal
|
|||||||
glGetShaderiv(screen_fragment_shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(screen_fragment_shader, GL_COMPILE_STATUS, &success);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
glGetShaderInfoLog(screen_fragment_shader, INFO_LOG_SIZE, 0, info_log);
|
||||||
|
|
||||||
glDeleteShader(screen_vertex_shader);
|
glDeleteShader(screen_vertex_shader);
|
||||||
glDeleteShader(screen_fragment_shader);
|
glDeleteShader(screen_fragment_shader);
|
||||||
|
|
||||||
@ -510,6 +560,8 @@ namespace glerminal
|
|||||||
|
|
||||||
update_sprites();
|
update_sprites();
|
||||||
|
|
||||||
|
glBindTextureUnit(0, m_sprites_texture);
|
||||||
|
|
||||||
// -- setup framebuffer --
|
// -- setup framebuffer --
|
||||||
glGenFramebuffers(1, &m_framebuffer);
|
glGenFramebuffers(1, &m_framebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||||
@ -526,9 +578,11 @@ namespace glerminal
|
|||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
|
||||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE, LAYER_COUNT, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE, LAYER_COUNT);
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_framebuffer_backing_texture, 0);
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_framebuffer_backing_texture, 0);
|
||||||
|
|
||||||
|
glBindTextureUnit(1, m_framebuffer_backing_texture);
|
||||||
|
|
||||||
// setup uniforms for screen shader
|
// setup uniforms for screen shader
|
||||||
glUseProgram(m_screen_program);
|
glUseProgram(m_screen_program);
|
||||||
}
|
}
|
||||||
@ -550,13 +604,25 @@ 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_layer_scales_buffer);
|
||||||
glDeleteProgram(m_program);
|
glDeleteProgram(m_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal::update_sprites()
|
void glerminal::update_sprites()
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
|
||||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, CELL_SIZE, CELL_SIZE, 256, 0, 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()
|
||||||
|
{
|
||||||
|
glNamedBufferData(m_layer_colors_buffer, sizeof(m_layer_colors), m_layer_colors, GL_DYNAMIC_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glerminal::update_layer_scales()
|
||||||
|
{
|
||||||
|
glNamedBufferData(m_layer_scales_buffer, sizeof(m_layer_scales), m_layer_scales, GL_DYNAMIC_READ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,6 +668,20 @@ 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)
|
||||||
|
{
|
||||||
|
if (!GLERMINAL_G) { return; }
|
||||||
|
|
||||||
|
GLERMINAL_G->layer_color(layer, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glerminal_layer_scale(unsigned char layer, float scale)
|
||||||
|
{
|
||||||
|
if (!GLERMINAL_G) { return; }
|
||||||
|
|
||||||
|
GLERMINAL_G->layer_scale(layer, scale);
|
||||||
|
}
|
||||||
|
|
||||||
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite)
|
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite)
|
||||||
{
|
{
|
||||||
if (!GLERMINAL_G) { return; }
|
if (!GLERMINAL_G) { return; }
|
||||||
|
Loading…
Reference in New Issue
Block a user