load and display bitmaps
This commit is contained in:
parent
857f368970
commit
0f5e6d9a4d
255
src/assets.c++
Normal file
255
src/assets.c++
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ass.h"
|
||||||
|
#include "rect-pack.h"
|
||||||
|
#include "batch.h"
|
||||||
|
|
||||||
|
#include <glad/gles2.h>
|
||||||
|
|
||||||
|
#include "main.h++"
|
||||||
|
|
||||||
|
static int read_vlq(unsigned char const *buf, size_t size, size_t &out) {
|
||||||
|
size_t outsize = buf[0];
|
||||||
|
unsigned outsizebytes = 1;
|
||||||
|
for (unsigned m = 0x80; outsize & m; m = m >> 1) {
|
||||||
|
outsizebytes++;
|
||||||
|
outsize &= ~m;
|
||||||
|
}
|
||||||
|
if (outsizebytes > size) {
|
||||||
|
return -outsizebytes;
|
||||||
|
}
|
||||||
|
for (unsigned i = 1; i < outsizebytes; i++) {
|
||||||
|
outsize = (outsize << 8) | buf[i];
|
||||||
|
}
|
||||||
|
out = outsize;
|
||||||
|
return outsizebytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
std::vector<std::string> filename;
|
||||||
|
std::vector<struct rect> rect;
|
||||||
|
std::vector<std::vector<unsigned char>> data;
|
||||||
|
} pictures = {};
|
||||||
|
|
||||||
|
static int decode_pic(struct rect const &r, std::vector<unsigned char> &data, unsigned char *out, size_t const xstride, size_t const ystride) {
|
||||||
|
if (data.size() != r.w * r.h) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (size_t y = 0; y < r.h; y++) {
|
||||||
|
for (size_t x = 0; x < r.w; x++) {
|
||||||
|
out[y * ystride + x * xstride] = data[y * r.w + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint util_compileShader(char *name, GLsizei size, GLchar const **strings, GLint *lengths, GLenum shaderType) {
|
||||||
|
GLuint shader = glCreateShader(shaderType);
|
||||||
|
if (shader == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glShaderSource(shader, size, strings, lengths);
|
||||||
|
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||||
|
if (success == false) {
|
||||||
|
char message[512];
|
||||||
|
glGetShaderInfoLog(shader, sizeof (message), NULL, message);
|
||||||
|
fprintf(stderr, "error: %s: %s\n", name, message);
|
||||||
|
glDeleteShader(shader);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint util_linkProgram(char *name, GLuint Vshader, GLuint Fshader) {
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
if (program == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(program, Vshader);
|
||||||
|
glAttachShader(program, Fshader);
|
||||||
|
|
||||||
|
glLinkProgram(program);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||||
|
if (success == false) {
|
||||||
|
char message[512];
|
||||||
|
glGetProgramInfoLog(program, sizeof (message), NULL, message);
|
||||||
|
fprintf(stderr, "error: %s: %s\n", name, message);
|
||||||
|
glDeleteProgram(program);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
int assets_load(FILE *file, char const *name) {
|
||||||
|
enum ass_status ret = assread(file, [](char const *filename_, size_t length, void const *data_, size_t size, void *ctx) -> int {
|
||||||
|
(void) ctx;
|
||||||
|
std::string filename = std::string(filename_, length);
|
||||||
|
auto pos = filename.find_last_of('.');
|
||||||
|
std::string const name = filename.substr(0, pos);
|
||||||
|
std::string const extension = pos == filename.npos? "": filename.substr(pos);
|
||||||
|
unsigned char const *data = (unsigned char const *) data_;
|
||||||
|
if (extension == ".shader") {
|
||||||
|
char const *vsrc = (char const *) data;
|
||||||
|
size_t len = strnlen(vsrc, size);
|
||||||
|
if (len == size) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char const *fsrc = vsrc + len + 1;
|
||||||
|
len = size - len - 1;
|
||||||
|
if (strnlen(fsrc, len) != len - 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vshader, 1, &vsrc, NULL);
|
||||||
|
glCompileShader(vshader);
|
||||||
|
GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fshader, 1, &fsrc, NULL);
|
||||||
|
glCompileShader(fshader);
|
||||||
|
|
||||||
|
int vsuccess, fsuccess;
|
||||||
|
glGetShaderiv(vshader, GL_COMPILE_STATUS, &vsuccess);
|
||||||
|
glGetShaderiv(fshader, GL_COMPILE_STATUS, &fsuccess);
|
||||||
|
if (vsuccess == false || fsuccess == false) {
|
||||||
|
char message[1024];
|
||||||
|
if (vsuccess == false) {
|
||||||
|
glGetShaderInfoLog(vshader, sizeof (message), NULL, message);
|
||||||
|
fprintf(stderr, "error: %s.vert: %s\n", name.c_str(), message);
|
||||||
|
}
|
||||||
|
if (fsuccess == false) {
|
||||||
|
glGetShaderInfoLog(fshader, sizeof (message), NULL, message);
|
||||||
|
fprintf(stderr, "error: %s.frag: %s\n", name.c_str(), message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
glAttachShader(program, vshader);
|
||||||
|
glAttachShader(program, fshader);
|
||||||
|
glLinkProgram(program);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||||
|
if (success == false) {
|
||||||
|
char message[1024];
|
||||||
|
glGetProgramInfoLog(program, sizeof (message), NULL, message);
|
||||||
|
fprintf(stderr, "error: %s: %s\n", name.c_str(), message);
|
||||||
|
glDeleteProgram(program);
|
||||||
|
} else {
|
||||||
|
programs[name] = program;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vshader);
|
||||||
|
glDeleteShader(fshader);
|
||||||
|
return vsuccess == false || fsuccess == false;
|
||||||
|
} else if (extension == ".picture") {
|
||||||
|
if (memcmp(data, "\xdd\xddpic\n\0\0", 8)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
data += 8; size -= 8;
|
||||||
|
size_t value;
|
||||||
|
struct rect r = {};
|
||||||
|
int result = read_vlq(data, size, value);
|
||||||
|
r.w = value + 1;
|
||||||
|
if (result < 0 || r.w - 1 != value) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
data += result; size -= result;
|
||||||
|
result = read_vlq(data, size, value);
|
||||||
|
r.h = value + 1;
|
||||||
|
if (result < 0 || r.h - 1 != value) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
data += result; size -= result;
|
||||||
|
std::vector<unsigned char> v(data, data + size);
|
||||||
|
pictures.filename.push_back(name);
|
||||||
|
pictures.rect.push_back(r);
|
||||||
|
pictures.data.push_back(v);
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}, NULL);
|
||||||
|
|
||||||
|
if (ret != ASS_OK) {
|
||||||
|
switch (ret) {
|
||||||
|
case ASS_OK: break;
|
||||||
|
case ASS_BAD: fprintf(stderr, "error: %s: malformed asset pack\n", name); break;
|
||||||
|
case ASS_USER: fprintf(stderr, "error: %s: malformed asset\n", name); break;
|
||||||
|
case ASS_TRUNC: fprintf(stderr, "error: %s: truncated asset pack\n", name); break;
|
||||||
|
case ASS_LAZY: fprintf(stderr, "error: %s: this asset pack will not load, sorry\n", name); break;
|
||||||
|
case ASS_MEM: fprintf(stderr, "error: %s: memory exhausted while trying to load asset pack\n", name); break;
|
||||||
|
case ASS_UNSUPPORTED: fprintf(stderr, "error: %s: unsupported asset pack version\n", name); break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pack_result res = guilotine(pictures.rect.data(), pictures.rect.size(), 512, 1);
|
||||||
|
if (res.bins == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t const stride = res.last_bin_size;
|
||||||
|
unsigned char *tex = new unsigned char [stride * stride];
|
||||||
|
memset(tex, 69, stride * stride);
|
||||||
|
for (size_t i = 0; i < pictures.rect.size(); i++) {
|
||||||
|
struct rect const &r = pictures.rect[i];
|
||||||
|
//fprintf(stderr, "%s: %ux%u +%u+%u @ %u %c\n", pictures.filename[i].c_str(), r.w, r.h, r.x, r.y, r.bin, r.flipped? '+': '-');
|
||||||
|
|
||||||
|
int ret = decode_pic(r, pictures.data[i], tex + r.y * stride + r.x, r.flipped? stride: 1, r.flipped? 1: stride);
|
||||||
|
if (ret) {
|
||||||
|
delete[] tex;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fprintf(stderr, "info: %u %u %u %u\n", res.bins, res.last_bin_size, res.last_bin_width, res.last_bin_height);
|
||||||
|
|
||||||
|
GLuint texture;
|
||||||
|
glGenTextures(1, &texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, stride, stride, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, tex);
|
||||||
|
delete[] tex;
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
unsigned tsize = 65536 / stride;
|
||||||
|
#else
|
||||||
|
unsigned tsize = 0;
|
||||||
|
for (unsigned s = stride; s & 0xffff; s <<= 1, tsize++)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pictures.rect.size(); i++) {
|
||||||
|
struct rect const &r = pictures.rect[i];
|
||||||
|
struct texture t = {.texture = texture, .x = r.x, .y = r.y, .size = tsize, .flipped = r.flipped};
|
||||||
|
textures[pictures.filename[i]] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pictures.rect.clear();
|
||||||
|
pictures.rect.shrink_to_fit();
|
||||||
|
pictures.data.clear();
|
||||||
|
pictures.data.shrink_to_fit();
|
||||||
|
pictures.filename.clear();
|
||||||
|
pictures.filename.shrink_to_fit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
5
src/assets.h++
Normal file
5
src/assets.h++
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
int assets_load(FILE *file, char const *name);
|
||||||
71
src/main.c++
71
src/main.c++
@ -9,39 +9,22 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#include "ass.h"
|
#include "batch.h"
|
||||||
|
#include "assets.h++"
|
||||||
|
#include "main.h++"
|
||||||
|
|
||||||
#define WINDOW_WIDTH 128
|
#define WINDOW_WIDTH 128
|
||||||
#define WINDOW_HEIGHT 128
|
#define WINDOW_HEIGHT 128
|
||||||
|
|
||||||
#if 0
|
#define BATCH_SIZE 1024
|
||||||
// something something string_view faster but actually cryptic error messages so w/e future me problem
|
|
||||||
#include <string_view>
|
|
||||||
struct string_hash {
|
|
||||||
using is_transparent = void;
|
|
||||||
[[nodiscard]] size_t operator()(const char *txt) const {
|
|
||||||
return std::hash<std::string_view>{}(txt);
|
|
||||||
}
|
|
||||||
[[nodiscard]] size_t operator()(std::string_view txt) const {
|
|
||||||
return std::hash<std::string_view>{}(txt);
|
|
||||||
}
|
|
||||||
[[nodiscard]] size_t operator()(const std::string &txt) const {
|
|
||||||
return std::hash<std::string>{}(txt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::unordered_map<std::string, unsigned, string_hash, std::equal_to<>> programs, textures;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct state {
|
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
float color;
|
std::unordered_map<std::string, unsigned> programs;
|
||||||
std::unordered_map<std::string, unsigned> programs, textures;
|
std::unordered_map<std::string, struct texture> textures;
|
||||||
};
|
|
||||||
|
|
||||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
SDL_AppResult SDL_AppInit(void **, int argc, char **argv) {
|
||||||
clock_t begin = clock();
|
clock_t begin = clock();
|
||||||
auto state = new (struct state);
|
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
@ -50,10 +33,10 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
|||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "60");
|
SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "60");
|
||||||
|
|
||||||
state->window = SDL_CreateWindow("suwi", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL /*| SDL_WINDOW_RESIZABLE*/ | SDL_WINDOW_TRANSPARENT);
|
window = SDL_CreateWindow("suwi", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL /*| SDL_WINDOW_RESIZABLE*/ | SDL_WINDOW_TRANSPARENT);
|
||||||
SDL_SetWindowMinimumSize(state->window, WINDOW_WIDTH, WINDOW_HEIGHT);
|
SDL_SetWindowMinimumSize(window, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
|
||||||
state->context = SDL_GL_CreateContext(state->window);
|
context = SDL_GL_CreateContext(window);
|
||||||
|
|
||||||
int version = gladLoadGLES2((GLADloadfunc) SDL_GL_GetProcAddress);
|
int version = gladLoadGLES2((GLADloadfunc) SDL_GL_GetProcAddress);
|
||||||
if (version == 0) {
|
if (version == 0) {
|
||||||
@ -75,35 +58,28 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
|||||||
perror(path.c_str());
|
perror(path.c_str());
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
if (assets_load(file, path.c_str())) {
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
file = fopen(argv[1], "rb");
|
file = fopen(argv[1], "rb");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
if (assets_load(file, argv[1])) {
|
||||||
if (assread(file, [](char const *name, size_t length, void const *data, size_t size, /* struct state *state */ void *ctx) -> int {
|
|
||||||
auto &state = *(struct state *) ctx;
|
|
||||||
std::string filename = std::string(name, length);
|
|
||||||
(void) name;
|
|
||||||
(void) length;
|
|
||||||
(void) data;
|
|
||||||
(void) size;
|
|
||||||
if (filename.ends_with(".glsl")) {
|
|
||||||
state.programs[filename];
|
|
||||||
}
|
|
||||||
state.textures[filename];
|
|
||||||
return 0;
|
|
||||||
}, state)) {
|
|
||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
batch_init(BATCH_SIZE, programs.at("spr2D"));
|
||||||
|
|
||||||
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
SDL_ShowWindow(state->window);
|
SDL_ShowWindow(window);
|
||||||
|
|
||||||
fprintf(stderr, "info: init took %lu ms\n", ((clock() - begin) * 1000) / CLOCKS_PER_SEC);
|
fprintf(stderr, "info: init took %lu ms\n", ((clock() - begin) * 1000) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
*appstate = state;
|
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,12 +122,15 @@ SDL_AppResult SDL_AppEvent(void *, SDL_Event *evt) {
|
|||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AppResult SDL_AppIterate(void *appstate) {
|
SDL_AppResult SDL_AppIterate(void *) {
|
||||||
auto &state = *(struct state *) appstate;
|
|
||||||
glClearColor(0.5, 0.5, 0.5, 0.0);
|
glClearColor(0.5, 0.5, 0.5, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
SDL_GL_SwapWindow(state.window);
|
struct crop c = {0, 0, 64, 64};
|
||||||
|
batch_blit(-32, -32, &textures.at("turret"), &c);
|
||||||
|
batch_flush();
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
32
src/main.h++
Normal file
32
src/main.h++
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/gles2.h>
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "batch.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// something something string_view faster but actually cryptic error messages so w/e future me problem
|
||||||
|
#include <string_view>
|
||||||
|
struct string_hash {
|
||||||
|
using is_transparent = void;
|
||||||
|
[[nodiscard]] size_t operator()(const char *txt) const {
|
||||||
|
return std::hash<std::string_view>{}(txt);
|
||||||
|
}
|
||||||
|
[[nodiscard]] size_t operator()(std::string_view txt) const {
|
||||||
|
return std::hash<std::string_view>{}(txt);
|
||||||
|
}
|
||||||
|
[[nodiscard]] size_t operator()(const std::string &txt) const {
|
||||||
|
return std::hash<std::string>{}(txt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::unordered_map<std::string, unsigned, string_hash, std::equal_to<>> programs, textures;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern SDL_Window *window;
|
||||||
|
extern SDL_GLContext context;
|
||||||
|
extern std::unordered_map<std::string, unsigned> programs;
|
||||||
|
extern std::unordered_map<std::string, struct texture> textures;
|
||||||
@ -95,7 +95,7 @@ struct pack_result guilotine(struct rect *rects, size_t items, unsigned maxsize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct pack_result guilotine_(struct rect **left_base, size_t left_count, unsigned maxwidth, unsigned maxheight, unsigned bins, unsigned maxbins) {
|
static struct pack_result guilotine_(struct rect **left_base, size_t left_count, unsigned maxwidth, unsigned maxheight, unsigned bins, unsigned maxbins) {
|
||||||
fprintf(stderr, "%zu %ux%u, %u\n", left_count, maxwidth, maxheight, maxbins - bins);
|
//fprintf(stderr, "%zu %ux%u, %u\n", left_count, maxwidth, maxheight, maxbins - bins);
|
||||||
struct rect **left = left_base;
|
struct rect **left = left_base;
|
||||||
unsigned in_last_bin = 0;
|
unsigned in_last_bin = 0;
|
||||||
size_t slot_count = 1;
|
size_t slot_count = 1;
|
||||||
@ -233,28 +233,8 @@ static struct pack_result guilotine_(struct rect **left_base, size_t left_count,
|
|||||||
//free(other_left);
|
//free(other_left);
|
||||||
free(tighter);
|
free(tighter);
|
||||||
|
|
||||||
#if 0
|
|
||||||
fprintf(stdout, "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 %u %u\">", (maxsize + 16) * bins - 16, maxsize);
|
|
||||||
for (unsigned i = 0; i < bins; i++) {
|
|
||||||
unsigned binx = (maxsize + 16) * i, biny = 0;
|
|
||||||
fprintf(stdout, "<view id=\"%u\" viewBox=\"%u %u %u %u\"/>", i, binx, biny, maxsize, maxsize);
|
|
||||||
}
|
|
||||||
fputs("<style>rect{stroke:black;}.bg{fill:gray;}.flipped{fill:green;}.normal{fill:blue}text{font-family:monospace;text-anchor:middle;alignment-baseline:central;}</style>", stdout);
|
|
||||||
for (unsigned i = 0; i < items; i++) {
|
|
||||||
unsigned w = rects[i].flipped? rects[i].h: rects[i].w;
|
|
||||||
unsigned h = rects[i].flipped? rects[i].w: rects[i].h;
|
|
||||||
unsigned binx = (maxsize + 16) * rects[i].bin, biny = 0;
|
|
||||||
fprintf(stdout, "<rect x=\"%u.5\" y=\"%u.5\" width=\"%u\" height=\"%u\" class=\"%s\"/><text x=\"%u\" y=\"%u\" style=\"font-size: %upx\">%u</text>", rects[i].x + binx, rects[i].y + biny, w - 1, h - 1, rects[i].flipped? "flipped": "normal", rects[i].x + w / 2 + binx, rects[i].y + h / 2 + biny, h > 20? 20: h, i);
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < slot_count; i++) {
|
|
||||||
unsigned binx = (maxsize + 16) * slots[i].bin, biny = 0;
|
|
||||||
fprintf(stdout, "<rect x=\"%u.5\" y=\"%u.5\" width=\"%u\" height=\"%u\" class=\"bg\"/>", slots[i].x + binx, slots[i].y + biny, slots[i].w - 1, slots[i].h - 1);
|
|
||||||
}
|
|
||||||
fputs("</svg>", stdout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(left_base);
|
free(left_base);
|
||||||
free(slots);
|
free(slots);
|
||||||
fprintf(stderr, "%u %u %u %u\n", bins, last_bin.last_bin_size, last_bin.last_bin_width, last_bin.last_bin_height);
|
//fprintf(stderr, "%u %u %u %u\n", bins, last_bin.last_bin_size, last_bin.last_bin_width, last_bin.last_bin_height);
|
||||||
return (struct pack_result) {bins, last_bin.last_bin_size, last_bin.last_bin_width, last_bin.last_bin_height};
|
return (struct pack_result) {bins, last_bin.last_bin_size, last_bin.last_bin_width, last_bin.last_bin_height};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ attribute vec2 aTexCoord;
|
|||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vTexCoord = aTexCoord;
|
vTexCoord = aTexCoord;
|
||||||
gl_Position = vec4(aVertCoord * vec2(1.0 / 256.0), 0.0, 1.0);
|
gl_Position = vec4(aVertCoord * vec2(1.0 / 64.0), 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -23,8 +23,9 @@ void main(void) {
|
|||||||
uniform sampler2D uTex;
|
uniform sampler2D uTex;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
if (texture2D(uTex, vTexCoord).r < 0.5) {
|
float pixel = texture2D(uTex, vTexCoord).r;
|
||||||
|
if (pixel < 0.5) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
gl_FragColor = vec4(1.0);
|
gl_FragColor = step(vec4(0.75, 0.75, 0.75, 0.5), vec4(pixel));
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user