Rework sprite API
This commit is contained in:
parent
e3a65072d8
commit
c89563338a
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
@ -2,20 +2,37 @@ cmake_minimum_required(VERSION 3.28)
|
|||||||
|
|
||||||
set(CMAKE_FOLDER examples)
|
set(CMAKE_FOLDER examples)
|
||||||
|
|
||||||
add_executable(basic WIN32
|
file(GLOB_RECURSE
|
||||||
basic.cpp
|
EXAMPLE_RESOURCES
|
||||||
|
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/resources/**.png
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(basic
|
foreach(RESOURCE_FILE ${EXAMPLE_RESOURCES})
|
||||||
PRIVATE
|
add_custom_command(
|
||||||
glerminal
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_FILE}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_FILE}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_FILE}
|
||||||
|
DEPENDS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_FILE}
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(GLOB_RECURSE
|
||||||
|
EXAMPLE_SOURCES
|
||||||
|
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(towers WIN32
|
list(TRANSFORM EXAMPLE_RESOURCES PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
|
||||||
towers.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(towers
|
foreach(SOURCE_FILE ${EXAMPLE_SOURCES})
|
||||||
PRIVATE
|
get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE)
|
||||||
glerminal
|
add_executable(${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${EXAMPLE_RESOURCES})
|
||||||
)
|
target_link_libraries(${SOURCE_FILENAME} PRIVATE glerminal)
|
||||||
|
endforeach()
|
46
examples/atlas.cpp
Normal file
46
examples/atlas.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <glerminal.h>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
glerminal_load_sprites_file("resources/atlas.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainloop(float dt)
|
||||||
|
{
|
||||||
|
static float time = 1;
|
||||||
|
|
||||||
|
time += dt;
|
||||||
|
|
||||||
|
if (time < 1.0f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 25; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 256; k++)
|
||||||
|
{
|
||||||
|
glerminal_set(i, j, k, rand() % 4);
|
||||||
|
glerminal_offset(i, j, k, (rand() * rand()) % 64 - 32, (rand() * rand()) % 64 - 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glerminal_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
glerminal_run(init, mainloop);
|
||||||
|
}
|
@ -6,16 +6,7 @@ namespace
|
|||||||
{
|
{
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
glerminal_update_sprite(1, {
|
glerminal_load_sprites_file("resources/basic.png");
|
||||||
0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x500000FF, 0x5000FF00,
|
|
||||||
0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00, 0x5000FF00
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mainloop(float dt)
|
void mainloop(float dt)
|
||||||
@ -39,7 +30,7 @@ namespace
|
|||||||
{
|
{
|
||||||
for (int k = 0; k < 256; k++)
|
for (int k = 0; k < 256; k++)
|
||||||
{
|
{
|
||||||
glerminal_set(i, j, k, rand() % 8 == 0);
|
glerminal_set(i, j, k, rand() % 3 == 0);
|
||||||
glerminal_offset(i, j, k, (rand() * rand()) % 64 - 32, (rand() * rand()) % 64 - 32);
|
glerminal_offset(i, j, k, (rand() * rand()) % 64 - 32, (rand() * rand()) % 64 - 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
examples/resources/atlas.png
(Stored with Git LFS)
Normal file
BIN
examples/resources/atlas.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
examples/resources/basic.png
(Stored with Git LFS)
Normal file
BIN
examples/resources/basic.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
examples/resources/towers.png
(Stored with Git LFS)
Normal file
BIN
examples/resources/towers.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -7,64 +7,48 @@ namespace
|
|||||||
{
|
{
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
glerminal_update_sprite(1,
|
glerminal_load_sprites_file("resources/towers.png");
|
||||||
{
|
|
||||||
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,
|
|
||||||
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++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
constexpr unsigned char c = 32;
|
constexpr unsigned char c = 0;
|
||||||
const unsigned char v = (255 - c) * powf((i - 1) / 256.0f, 2.0f) + c;
|
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;
|
const unsigned int j = (0x7F << 24) | (v << 16) | (v << 8) | v;
|
||||||
glerminal_layer_color(i, j);
|
glerminal_layer_color(i, j);
|
||||||
glerminal_layer_scale(i, i / 256.0f + 1);
|
glerminal_layer_scale(i, i / 256.0f + 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void mainloop(float dt)
|
|
||||||
{
|
|
||||||
static float time = 1;
|
|
||||||
|
|
||||||
time += dt;
|
|
||||||
|
|
||||||
if (time < 0.15f)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
time = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int cx = rand() % 40;
|
|
||||||
const int cy = rand() % 25;
|
|
||||||
|
|
||||||
for (int i = 0; i < 40; i++)
|
for (int i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 25; j++)
|
for (int j = 0; j < 25; j++)
|
||||||
{
|
{
|
||||||
const int c = rand() % 224 + 32;
|
const int c = rand() % 224 + 32;
|
||||||
for (int k = 0; k < 256; k++)
|
for (int k = 0; k < c; k++)
|
||||||
{
|
|
||||||
if (k < c)
|
|
||||||
{
|
{
|
||||||
glerminal_set(i, j, k, 1);
|
glerminal_set(i, j, k, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainloop(float dt)
|
||||||
|
{
|
||||||
|
static float time = 0;
|
||||||
|
|
||||||
|
time += dt;
|
||||||
|
|
||||||
|
const float cx = 20.0f * cosf(time / 3.1415f) + 20.0f;
|
||||||
|
const float cy = 12.5f * sinf(time / 3.1415f) + 12.5f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 25; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 256; k++)
|
||||||
|
{
|
||||||
const float ox = 0.01f * k * (i - cx);
|
const float ox = 0.01f * k * (i - cx);
|
||||||
const float oy = 0.01f * k * (j - cy);
|
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));
|
glerminal_offset(i, j, k, ox + (1 + 0.004f * k) * cosf(i + k * 6.2832f / 128.0f + 3.1415f * time), oy + (1 + 0.004f * k) * sinf(j + k * 6.2832f / 128.0f + 3.1415f * time));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glerminal_set(i, j, k, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,20 +6,9 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
GLERMINAL_CELL_SIZE = 8,
|
|
||||||
GLERMINAL_CELL_AREA = GLERMINAL_CELL_SIZE * GLERMINAL_CELL_SIZE
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*glerminal_init_cb)();
|
typedef void (*glerminal_init_cb)();
|
||||||
typedef void (*glerminal_main_cb)(float dt);
|
typedef void (*glerminal_main_cb)(float dt);
|
||||||
|
|
||||||
typedef struct glerminal_sprite
|
|
||||||
{
|
|
||||||
unsigned int data[GLERMINAL_CELL_AREA];
|
|
||||||
} glerminal_sprite;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Call init once, then run the application's mainloop
|
* @brief Call init once, then run the application's mainloop
|
||||||
* @param init initialization callback
|
* @param init initialization callback
|
||||||
@ -71,12 +60,9 @@ void glerminal_layer_color(unsigned char layer, unsigned int color);
|
|||||||
*/
|
*/
|
||||||
void glerminal_layer_scale(unsigned char layer, float scale);
|
void glerminal_layer_scale(unsigned char layer, float scale);
|
||||||
|
|
||||||
/**
|
void glerminal_load_sprites_file(const char* filename);
|
||||||
* @brief Upload sprite to the given sprite ID
|
|
||||||
* @param id The ID of the sprite to change
|
void glerminal_load_sprites_buffer(unsigned char width, unsigned char height, const unsigned int* buffer);
|
||||||
* @param sprite The new sprite
|
|
||||||
*/
|
|
||||||
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -3,24 +3,23 @@
|
|||||||
|
|
||||||
#include "glerminal.h"
|
#include "glerminal.h"
|
||||||
|
|
||||||
|
#include <stb_image.h>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#endif
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace glerminal
|
namespace glerminal
|
||||||
{
|
{
|
||||||
constexpr unsigned int SCREEN_WIDTH = 1280;
|
constexpr unsigned int SCREEN_WIDTH = 1280;
|
||||||
constexpr unsigned int SCREEN_HEIGHT = 800;
|
constexpr unsigned int SCREEN_HEIGHT = 800;
|
||||||
constexpr unsigned int CELL_SIZE = GLERMINAL_CELL_SIZE;
|
constexpr unsigned int CELL_SIZE = 8;
|
||||||
constexpr unsigned int CELL_SCALE = 4;
|
constexpr unsigned int CELL_SCALE = 4;
|
||||||
|
constexpr unsigned int LAYER_COUNT = 256;
|
||||||
constexpr unsigned int GRID_WIDTH = SCREEN_WIDTH / (CELL_SIZE * CELL_SCALE);
|
constexpr unsigned int GRID_WIDTH = SCREEN_WIDTH / (CELL_SIZE * CELL_SCALE);
|
||||||
constexpr unsigned int GRID_HEIGHT = SCREEN_HEIGHT / (CELL_SIZE * CELL_SCALE);
|
constexpr unsigned int GRID_HEIGHT = SCREEN_HEIGHT / (CELL_SIZE * CELL_SCALE);
|
||||||
constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT;
|
constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT;
|
||||||
constexpr unsigned int LAYER_COUNT = 256;
|
|
||||||
|
|
||||||
class glerminal
|
class glerminal
|
||||||
{
|
{
|
||||||
@ -43,8 +42,7 @@ namespace glerminal
|
|||||||
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);
|
||||||
|
void load_atlas(unsigned char w, unsigned char h, const unsigned int* data);
|
||||||
void update_sprite(unsigned char id, glerminal_sprite sprite);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// glfw data
|
// glfw data
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#define STBI_ONLY_PNG
|
||||||
|
#define STBI_MAX_DIMENSIONS 128
|
||||||
#include "glerminal-private.h"
|
#include "glerminal-private.h"
|
||||||
|
|
||||||
#define GRID_SIZE_UNIFORM_NAME "grid_size"
|
#define GRID_SIZE_UNIFORM_NAME "grid_size"
|
||||||
@ -255,10 +258,26 @@ namespace glerminal
|
|||||||
m_layer_scales[layer] = scale;
|
m_layer_scales[layer] = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal::update_sprite(unsigned char id, glerminal_sprite sprite)
|
void glerminal::load_atlas(unsigned char w, unsigned char h, const unsigned int* data)
|
||||||
{
|
{
|
||||||
// does this work?
|
// each row of the atlas
|
||||||
reinterpret_cast<glerminal_sprite*>(m_sprites)[id] = sprite;
|
for (int j = 0; j < h; j++)
|
||||||
|
{
|
||||||
|
// each column of the atlas
|
||||||
|
for (int i = 0; i < w; i++)
|
||||||
|
{
|
||||||
|
// each row of the individual sprite
|
||||||
|
for (int k = 0; k < CELL_SIZE; k++)
|
||||||
|
{
|
||||||
|
// offset from base address in 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;
|
||||||
|
|
||||||
|
memcpy(m_sprites + CELL_SIZE * dst_offset, data + CELL_SIZE * src_offset, CELL_SIZE * sizeof(unsigned int));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal::init_glfw()
|
void glerminal::init_glfw()
|
||||||
@ -682,9 +701,29 @@ void glerminal_layer_scale(unsigned char layer, float scale)
|
|||||||
GLERMINAL_G->layer_scale(layer, scale);
|
GLERMINAL_G->layer_scale(layer, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite)
|
void glerminal_load_sprites_file(const char* filename)
|
||||||
{
|
{
|
||||||
if (!GLERMINAL_G) { return; }
|
if (!GLERMINAL_G) { return; }
|
||||||
|
|
||||||
GLERMINAL_G->update_sprite(id, sprite);
|
int w, h;
|
||||||
|
stbi_uc* const buffer = stbi_load(filename, &w, &h, nullptr, 4);
|
||||||
|
|
||||||
|
// verify atlas size is a multiple of CELL_SIZE in each dimension
|
||||||
|
if (w % glerminal::CELL_SIZE == 0 && h % glerminal::CELL_SIZE == 0)
|
||||||
|
{
|
||||||
|
GLERMINAL_G->load_atlas(w / glerminal::CELL_SIZE, h / glerminal::CELL_SIZE, reinterpret_cast<unsigned int*>(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
stbi_image_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glerminal_load_sprites_buffer(unsigned char width, unsigned char height, const unsigned int* buffer)
|
||||||
|
{
|
||||||
|
if (!GLERMINAL_G) { return; }
|
||||||
|
|
||||||
|
// verify atlas size is a multiple of CELL_SIZE in each dimension
|
||||||
|
if (width % glerminal::CELL_SIZE == 0 && height % glerminal::CELL_SIZE == 0)
|
||||||
|
{
|
||||||
|
GLERMINAL_G->load_atlas(width / glerminal::CELL_SIZE, height / glerminal::CELL_SIZE, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
7985
source/stb_image.h
Normal file
7985
source/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user