string ref animation

This commit is contained in:
John Alanbrook 2024-10-19 05:34:08 -05:00
parent 27d7c5ab02
commit f823e6b839
6 changed files with 69 additions and 35 deletions

View file

@ -137,7 +137,7 @@ json.doc = {
};
Resources.scripts = ["jsoc", "jsc", "jso", "js"];
Resources.images = ["qoi", "png", "gif", "jpg", "jpeg"];
Resources.images = ["qoi", "png", "gif", "jpg", "jpeg", "ase", "aseprite"];
Resources.sounds = ["wav", "flac", "mp3", "qoa"];
Resources.fonts = ["ttf"];
Resources.is_image = function (path) {

View file

@ -223,6 +223,7 @@ var sheetsize = 1024;
function pack_into_sheet(images)
{
return;
if (!Array.isArray(images)) images = [images];
if (images[0].texture.width > 300 && images[0].texture.height > 300) return;
sheet_frames = sheet_frames.concat(images);
@ -253,6 +254,9 @@ function pack_into_sheet(images)
return spritesheet;
}
// The game texture cache is a cache of all images that have been loaded. It looks like this ...
// Any request to it returns an image, which is a texture and rect. But they can
game.texture = function (path) {
if (!path) return game.texture("icons/no_tex.gif");
@ -265,16 +269,11 @@ game.texture = function (path) {
game.texture.time_cache[path] = io.mod(path);
return game.texture.cache[path];
}
var cachestr = path;
if (parts[1])
cachestr += parts[1];
var frame;
var anim_str;
if (parts.length > 1) {
// it's an animation
path = parts[0];
parts = parts[1].split('_'); // For a gif, it might be 'water.gif:3', but for an ase it might be 'water.ase:run_3', meaning the third frame of the 'run' animation
if (parts.length === 1)
frame = Number(parts[0]);
@ -284,19 +283,53 @@ game.texture = function (path) {
}
} else
parts = undefined;
var ret;
if (ret = game.texture.cache[path]) {
if (ret.texture) return ret;
if (!parts) return ret;
if (game.texture.cache[cachestr]) return game.texture.cache[path];
var tex = os.make_texture(path.split(':')[0]);
return ret[anim_str].frames[frame];
}
var ext = path.ext();
if (ext === 'ase' || ext === 'aseprite') {
anim = os.make_aseprite(path);
if (!anim) return;
// load all into gpu
for (var a in anim)
for (let frame of anim[a].frames)
frame.texture.load_gpu();
game.texture.cache[path] = anim;
ret = game.texture.cache[path];
if (!parts) return ret;
return ret[anim_str].frames[frame];
}
if (ext === 'gif') {
console.info(path);
anim = os.make_gif(path);
if (!anim) return;
if (anim.frames.length === 1) {
anim.texture = anim.frames[0].texture;
anim.rect = anim.frames[0].rect;
}
game.texture.cache[path] = anim;
console.info("LOADING INTO GPU");
anim.frames[0].texture.load_gpu();
console.info(json.encode(anim));
return anim;
}
var tex = os.make_texture(path);
if (!tex) return;
var image;
var ext = path.ext();
var anim;
if (ext === 'ase' || ext === 'aseprite') {
anim = os.make_aseprite(path);
}
if (!anim) {
image = {
texture: tex,
@ -321,12 +354,12 @@ game.texture = function (path) {
tex = spritesheet;
}
game.texture.cache[cachestr] = image;
game.texture.cache[path] = image;
game.texture.time_cache[path] = io.mod(path);
tex.load_gpu();
return game.texture.cache[cachestr];
return game.texture.cache[path];
};
game.texture.cache = {};
game.texture.time_cache = {};

View file

@ -2,6 +2,7 @@
#include "render.h"
#include "sokol/sokol_app.h"
#include "log.h"
#include "imgui.h"
#include "implot.h"
#include "imnodes.h"
@ -350,27 +351,28 @@ JSC_CCALL(imgui_popid, ImGui::PopID(); )
JSC_CCALL(imgui_image,
texture *tex = js2texture(argv[0]);
if (!tex->simgui.id) {
simgui_image_desc_t simgd;
simgd.image = tex->id;
simgd.sampler = std_sampler;
tex->simgui = simgui_make_image(&simgd);
}
simgui_image_desc_t sg = {};
sg.image = tex->id;
sg.sampler = std_sampler;
simgui_image_t ss = simgui_make_image(&sg);
ImGui::Image(simgui_imtextureid(tex->simgui), ImVec2(tex->width, tex->height), ImVec2(0,0), ImVec2(1,1));
ImGui::Image(simgui_imtextureid(ss), ImVec2(tex->width, tex->height), ImVec2(0,0), ImVec2(1,1));
simgui_destroy_image(ss);
)
JSC_SCALL(imgui_imagebutton,
texture *tex = js2texture(argv[1]);
if (!tex->simgui.id) {
simgui_image_desc_t simgd;
simgd.image = tex->id;
simgd.sampler = std_sampler;
tex->simgui = simgui_make_image(&simgd);
}
simgui_image_desc_t sg = {};
sg.image = tex->id;
sg.sampler = std_sampler;
simgui_image_t ss = simgui_make_image(&sg);
if (ImGui::ImageButton(str, simgui_imtextureid(tex->simgui), ImVec2(tex->width, tex->height)))
if (ImGui::ImageButton(str, simgui_imtextureid(ss), ImVec2(tex->width, tex->height)))
script_call_sym(argv[2], 0, NULL);
simgui_destroy_image(ss);
)
JSC_CCALL(imgui_sameline, ImGui::SameLine(js2number(argv[0])) )
@ -876,7 +878,9 @@ static int started = 0;
JSValue gui_init(JSContext *js)
{
simgui_desc_t sdesc = {};
simgui_desc_t sdesc = {
.image_pool_size = 1024
};
simgui_setup(&sdesc);
ImGuiIO& io = ImGui::GetIO();

View file

@ -3387,7 +3387,6 @@ JSC_SCALL(os_make_gif,
tex->data = stbi_load_gif_from_memory(raw, rawlen, &delays, &tex->width, &tex->height, &frames, &n, 4);
JSValue gif = JS_NewObject(js);
js_setpropstr(gif, "texture", texture2js(tex));
JSValue delay_arr = JS_NewArray(js);
float yslice = 1.0/frames;
@ -3400,10 +3399,11 @@ JSC_SCALL(os_make_gif,
.w = 1,
.h = yslice
}));
js_setpropstr(frame, "texture", texture2js(tex));
js_setprop_num(delay_arr, i, frame);
}
js_setpropstr(gif, "delays", delay_arr);
js_setpropstr(gif, "frames", delay_arr);
free(delays);

View file

@ -219,8 +219,6 @@ void texture_free(texture *tex)
if (!tex) return;
if (tex->data)
free(tex->data);
if (tex->simgui.id)
simgui_destroy_image(tex->simgui);
free(tex);
}

View file

@ -24,7 +24,6 @@ extern struct rect ST_UNIT;
/* Represents an actual texture on the GPU */
struct texture {
sg_image id; /* ID reference for the GPU memory location of the texture */
simgui_image_t simgui;
int width;
int height;
HMM_Vec3 dimensions;