fix videos, gifs, aseprite
This commit is contained in:
@@ -87,7 +87,7 @@ if get_option('enet')
|
||||
endif
|
||||
|
||||
sources = []
|
||||
src += ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c','texture.c', 'timer.c', 'transform.c','warp.c','yugine.c', 'wildmatch.c', 'cv.cpp']
|
||||
src += ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c', 'timer.c', 'transform.c','warp.c','yugine.c', 'wildmatch.c', 'cv.cpp']
|
||||
|
||||
imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp']
|
||||
|
||||
|
||||
@@ -1014,6 +1014,9 @@ render.tile = function tile(image, rect = [0,0], color = Color.white)
|
||||
if (typeof image === "string")
|
||||
image = game.texture(image);
|
||||
|
||||
render._main.tile(image, rect, undefined, 1);
|
||||
return;
|
||||
|
||||
var tex = image.texture;
|
||||
if (!tex) return;
|
||||
|
||||
@@ -1136,10 +1139,6 @@ render.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.wh
|
||||
render.draw(shape.quad);
|
||||
};
|
||||
|
||||
function endframe() {
|
||||
tdraw = 0;
|
||||
}
|
||||
|
||||
var textssbos = [];
|
||||
var tdraw = 0;
|
||||
var cur_font = undefined;
|
||||
@@ -1191,6 +1190,16 @@ render.draw = function render_draw(mesh, ssbo, inst = 1, e_start = 0) {
|
||||
render.spdraw(e_start, cur.bind.count, inst);
|
||||
};
|
||||
|
||||
render.viewport = function(rect)
|
||||
{
|
||||
render._main.viewport(rect);
|
||||
}
|
||||
|
||||
render.scissor = function(rect)
|
||||
{
|
||||
render.viewport(rect)
|
||||
}
|
||||
|
||||
// Camera viewport is a rectangle with the bottom left corner defined as x,y. Units are pixels on the window.
|
||||
function camviewport() {
|
||||
var aspect = (((this.viewport[2] - this.viewport[0]) / (this.viewport[3] - this.viewport[1])) * prosperon.size.x) / prosperon.size.y;
|
||||
@@ -1423,75 +1432,19 @@ var imgui_fn = function imgui_fn() {
|
||||
var clearcolor = [100,149,237,255].scale(1/255);
|
||||
prosperon.render = function prosperon_render() {
|
||||
try{
|
||||
// render.glue_pass();
|
||||
render._main.draw_color(clearcolor);
|
||||
render._main.clear();
|
||||
/* render.set_view(prosperon.camera.transform);
|
||||
render.set_projection_ortho({
|
||||
l:-prosperon.camera.size.x/2,
|
||||
r:prosperon.camera.size.x/2,
|
||||
b:-prosperon.camera.size.y/2,
|
||||
t:prosperon.camera.size.y/2
|
||||
}, prosperon.camera.near,prosperon.camera.far);
|
||||
render.viewport(prosperon.camera.view(), false);
|
||||
|
||||
if (render.draw_sprites) render.sprites();
|
||||
|
||||
if (render.draw_particles) draw_emitters();
|
||||
*/
|
||||
// render.fillmask(0);
|
||||
// render.forceflush();
|
||||
/* render.set_projection_ortho({
|
||||
l:0,
|
||||
r:prosperon.camera.size.x,
|
||||
b:-prosperon.camera.size.y,
|
||||
t:0
|
||||
},-1,1);
|
||||
*/
|
||||
// render.set_view(unit_transform);
|
||||
// set to world cam
|
||||
prosperon.draw();
|
||||
if (render.draw_hud) prosperon.hud();
|
||||
// render.forceflush();
|
||||
|
||||
/* render.set_projection_ortho({
|
||||
l:0,
|
||||
r:prosperon.size.x,
|
||||
b:-prosperon.size.y,
|
||||
t:0
|
||||
},-1,1);
|
||||
render.viewport({
|
||||
t:0,
|
||||
height:prosperon.size.y,
|
||||
width:prosperon.size.x,
|
||||
l:0
|
||||
}, false);
|
||||
*/
|
||||
// prosperon.app();
|
||||
// render.forceflush();
|
||||
// if (debug.show) imgui_fn();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
} finally {
|
||||
// random tracy image
|
||||
/* var vals = Object.values(game.texture.cache);
|
||||
var tex = vals[Math.floor(Math.random()*vals.length)].texture;
|
||||
var texdata = os.tex_data(tex)
|
||||
tracy.image(texdata, tex.width, tex.height);
|
||||
*/
|
||||
// render.end_pass();
|
||||
// render.commit();
|
||||
render._main.present();
|
||||
endframe();
|
||||
tracy.gpu_collect();
|
||||
tracy.end_frame();
|
||||
tracy.gpu_sync();
|
||||
|
||||
/* var rtinfo = os.rt_info();
|
||||
for (var i in rtinfo) {
|
||||
console.log(`${i} is ${rtinfo[i]}`);
|
||||
tracy.plot(i, rtinfo[i]);
|
||||
}*/
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1537,7 +1490,8 @@ prosperon.process = function process() {
|
||||
*/
|
||||
}
|
||||
|
||||
tracy.gpu_zone(prosperon.render);
|
||||
prosperon.render();
|
||||
// tracy.gpu_zone(prosperon.render);
|
||||
};
|
||||
|
||||
return { render };
|
||||
|
||||
@@ -301,7 +301,7 @@ Cmdline.register_order(
|
||||
if (io.exists("config.js")) global.mixin("config.js");
|
||||
else console.warn("No config.js file found. Starting with default parameters.");
|
||||
var window = game.engine_start(prosperon);
|
||||
var renderer = window.make_renderer("vulkan");
|
||||
var renderer = window.make_renderer("gpu");
|
||||
render._main = renderer;
|
||||
|
||||
prosperon.init();
|
||||
|
||||
@@ -112,19 +112,19 @@ Ease.elastic = {
|
||||
Ease.elastic.c4 = (2 * Math.PI) / 3;
|
||||
Ease.elastic.c5 = (2 * Math.PI) / 4.5;
|
||||
|
||||
var tween = function (from, to, time, fn, endfn) {
|
||||
var start = profile.secs(profile.now());
|
||||
var tween = function (from, to, time, fn) {
|
||||
var start = profile.now()
|
||||
|
||||
var update = function tween_update(dt) {
|
||||
var elapsed = profile.secs(profile.now()) - start;
|
||||
var elapsed = profile.now() - start;
|
||||
fn(from.lerp(to, elapsed / time));
|
||||
if (elapsed >= time) {
|
||||
fn(to);
|
||||
if (stop.then) stop.then();
|
||||
stop();
|
||||
endfn?.();
|
||||
}
|
||||
};
|
||||
var stop = Register.update.register(update);
|
||||
console.log(update)
|
||||
return stop;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "datastream.h"
|
||||
|
||||
#include "limits.h"
|
||||
#include "texture.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "font.h"
|
||||
@@ -12,27 +11,10 @@
|
||||
|
||||
void datastream_free(JSRuntime *rt,datastream *ds)
|
||||
{
|
||||
// sg_destroy_image(ds->img);
|
||||
plm_destroy(ds->plm);
|
||||
free(ds);
|
||||
}
|
||||
|
||||
//void soundstream_fillbuf(struct datastream *ds, soundbyte *buf, int frames) {
|
||||
// for (int i = 0; i < frames*CHANNELS; i++)
|
||||
// buf[i] = ringshift(ds->ring);
|
||||
//}
|
||||
|
||||
static void render_frame(plm_t *mpeg, plm_frame_t *frame, struct datastream *ds) {
|
||||
if (ds->dirty) return;
|
||||
uint8_t rgb[frame->height*frame->width*4];
|
||||
memset(rgb,255,frame->height*frame->width*4);
|
||||
plm_frame_to_rgba(frame, rgb, frame->width*4);
|
||||
// sg_image_data imgd = {0};
|
||||
// imgd.subimage[0][0] = SG_RANGE(rgb);
|
||||
// sg_update_image(ds->img, &imgd);
|
||||
ds->dirty = true;
|
||||
}
|
||||
|
||||
static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream *ds) {
|
||||
// for (int i = 0; i < samples->count * CHANNELS; i++)
|
||||
// ringpush(ds->ring, samples->interleaved[i]);
|
||||
@@ -41,41 +23,20 @@ static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream
|
||||
struct datastream *ds_openvideo(void *raw, size_t rawlen)
|
||||
{
|
||||
struct datastream *ds = malloc(sizeof(*ds));
|
||||
ds->plm = plm_create_with_memory(raw, rawlen, 0);
|
||||
free(raw);
|
||||
void *newraw = malloc(rawlen);
|
||||
memcpy(newraw,raw,rawlen);
|
||||
ds->plm = plm_create_with_memory(newraw, rawlen, 1);
|
||||
|
||||
if (!ds->plm)
|
||||
if (!ds->plm) {
|
||||
free(ds);
|
||||
free(newraw);
|
||||
return NULL;
|
||||
|
||||
/* ds->img = sg_make_image(&(sg_image_desc){
|
||||
.width = plm_get_width(ds->plm),
|
||||
.height = plm_get_height(ds->plm),
|
||||
.usage = SG_USAGE_STREAM,
|
||||
.type = SG_IMAGETYPE_2D,
|
||||
.pixel_format = SG_PIXELFORMAT_RGBA8,
|
||||
});
|
||||
*/
|
||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||
|
||||
return ds;
|
||||
|
||||
// ds->ring = ringnew(ds->ring, 8192);
|
||||
// plugin_node(make_node(ds, soundstream_fillbuf, NULL), masterbus);
|
||||
|
||||
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
||||
plm_set_loop(ds->plm, false);
|
||||
|
||||
plm_set_audio_enabled(ds->plm, true);
|
||||
plm_set_audio_stream(ds->plm, 0);
|
||||
|
||||
// Adjust the audio lead time according to the audio_spec buffer size
|
||||
// plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE);
|
||||
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
void ds_advance(struct datastream *ds, double s) {
|
||||
ds->dirty = false;
|
||||
plm_decode(ds->plm, s);
|
||||
}
|
||||
|
||||
@@ -83,13 +44,6 @@ void ds_seek(struct datastream *ds, double time) {
|
||||
plm_seek(ds->plm, time, false);
|
||||
}
|
||||
|
||||
void ds_advanceframes(struct datastream *ds, int frames) {
|
||||
for (int i = 0; i < frames; i++) {
|
||||
plm_frame_t *frame = plm_decode_video(ds->plm);
|
||||
render_frame(ds->plm, frame, ds);
|
||||
}
|
||||
}
|
||||
|
||||
double ds_length(struct datastream *ds) {
|
||||
return plm_get_duration(ds->plm);
|
||||
}
|
||||
|
||||
@@ -5,26 +5,23 @@
|
||||
#include <stdint.h>
|
||||
#include <quickjs.h>
|
||||
|
||||
struct soundstream;
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
struct datastream {
|
||||
plm_t *plm;
|
||||
JSValue callback;
|
||||
JSContext *js;
|
||||
int width;
|
||||
int height;
|
||||
int dirty;
|
||||
};
|
||||
|
||||
typedef struct datastream datastream;
|
||||
|
||||
struct texture;
|
||||
|
||||
void datastream_free(JSRuntime *rt,datastream *ds);
|
||||
|
||||
struct datastream *ds_openvideo(void *raw, size_t rawlen);
|
||||
struct texture *ds_maketexture(struct datastream *);
|
||||
void ds_advance(struct datastream *ds, double);
|
||||
void ds_advance(struct datastream *ds, double); // advance time in seconds
|
||||
void ds_seek(struct datastream *ds, double);
|
||||
void ds_advanceframes(struct datastream *ds, int frames);
|
||||
void ds_pause(struct datastream *ds);
|
||||
void ds_stop(struct datastream *ds);
|
||||
int ds_videodone(struct datastream *ds);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "render.h"
|
||||
#include "HandmadeMath.h"
|
||||
#include <quickjs.h>
|
||||
#include "texture.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include "render.h"
|
||||
|
||||
|
||||
@@ -1431,6 +1431,7 @@ JSC_CCALL(game_renderers,
|
||||
JSC_CCALL(game_cameras,
|
||||
int num;
|
||||
SDL_CameraID *ids = SDL_GetCameras(&num);
|
||||
if (num == 0) return JS_UNDEFINED;
|
||||
JSValue jsids = JS_NewArray(js);
|
||||
for (int i = 0; i < num; i++)
|
||||
JS_SetPropertyUint32(js,jsids, i, number2js(js,ids[i]));
|
||||
@@ -2306,24 +2307,20 @@ static const JSCFunctionListEntry js_transform_funcs[] = {
|
||||
};
|
||||
|
||||
JSC_CCALL(datastream_time, return number2js(js,plm_get_time(js2datastream(js,self)->plm)); )
|
||||
|
||||
JSC_CCALL(datastream_advance_frames, ds_advanceframes(js2datastream(js,self), js2number(js,argv[0])))
|
||||
|
||||
JSC_CCALL(datastream_seek, ds_seek(js2datastream(js,self), js2number(js,argv[0])))
|
||||
|
||||
JSC_CCALL(datastream_advance, ds_advance(js2datastream(js,self), js2number(js,argv[0])))
|
||||
|
||||
JSC_CCALL(datastream_duration, return number2js(js,ds_length(js2datastream(js,self))))
|
||||
|
||||
JSC_CCALL(datastream_framerate, return number2js(js,plm_get_framerate(js2datastream(js,self)->plm)))
|
||||
|
||||
JSC_GETSET_CALLBACK(datastream, callback)
|
||||
|
||||
static const JSCFunctionListEntry js_datastream_funcs[] = {
|
||||
MIST_FUNC_DEF(datastream, time, 0),
|
||||
MIST_FUNC_DEF(datastream, advance_frames, 1),
|
||||
MIST_FUNC_DEF(datastream, seek, 1),
|
||||
MIST_FUNC_DEF(datastream, advance, 1),
|
||||
MIST_FUNC_DEF(datastream, duration, 0),
|
||||
MIST_FUNC_DEF(datastream, framerate, 0),
|
||||
CGETSET_ADD(datastream, callback),
|
||||
};
|
||||
|
||||
JSC_GETSET_CALLBACK(timer, fn)
|
||||
@@ -2663,8 +2660,6 @@ JSC_CCALL(os_make_texture,
|
||||
void *raw = JS_GetArrayBuffer(js, &len, argv[0]);
|
||||
if (!raw) return JS_ThrowReferenceError(js, "could not load texture with array buffer");
|
||||
|
||||
struct texture *tex = calloc(1, sizeof(*tex));
|
||||
|
||||
int n, width, height;
|
||||
void *data = stbi_load_from_memory(raw, len, &width, &height, &n, 0);
|
||||
|
||||
@@ -2696,33 +2691,24 @@ JSC_CCALL(os_make_gif,
|
||||
if (!raw) return JS_ThrowReferenceError(js, "could not load gif from supplied array buffer");
|
||||
|
||||
int n;
|
||||
texture *tex = calloc(1,sizeof(*tex));
|
||||
int frames;
|
||||
int *delays;
|
||||
tex->data = stbi_load_gif_from_memory(raw, rawlen, &delays, &tex->width, &tex->height, &frames, &n, 4);
|
||||
tex->height *= frames;
|
||||
int width;
|
||||
int height;
|
||||
void *pixels = stbi_load_gif_from_memory(raw, rawlen, &delays, &width, &height, &frames, &n, 4);
|
||||
|
||||
JSValue gif = JS_NewObject(js);
|
||||
JSValue delay_arr = JS_NewArray(js);
|
||||
JSValue jstex = JS_UNDEFINED; //texture2js(js,tex);
|
||||
|
||||
float yslice = 1.0/frames;
|
||||
for (int i = 0; i < frames; i++) {
|
||||
JSValue frame = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, frame, "time", number2js(js,(float)delays[i]/1000.0));
|
||||
JS_SetPropertyStr(js, frame, "rect", rect2js(js,(rect){
|
||||
.x = 0,
|
||||
.y = yslice*i,
|
||||
.w = 1,
|
||||
.h = yslice
|
||||
}));
|
||||
JS_SetPropertyStr(js, frame, "texture", JS_DupValue(js,jstex));
|
||||
SDL_Surface *framesurf = SDL_CreateSurfaceFrom(width,height,SDL_PIXELFORMAT_RGBA32,pixels+(width*height*4*i), width*4);
|
||||
JS_SetPropertyStr(js, frame, "surface", SDL_Surface2js(js,framesurf));
|
||||
JS_SetPropertyUint32(js, delay_arr, i, frame);
|
||||
}
|
||||
|
||||
JS_SetPropertyStr(js, gif, "frames", delay_arr);
|
||||
JS_FreeValue(js,jstex);
|
||||
|
||||
free(delays);
|
||||
|
||||
ret = gif;
|
||||
@@ -2731,12 +2717,8 @@ JSC_CCALL(os_make_gif,
|
||||
JSValue aseframe2js(JSContext *js, ase_frame_t aframe)
|
||||
{
|
||||
JSValue frame = JS_NewObject(js);
|
||||
texture *tex = calloc(1,sizeof(*tex));
|
||||
tex->width = aframe.ase->w;
|
||||
tex->height = aframe.ase->h;
|
||||
tex->data = malloc(tex->width*tex->height*4);
|
||||
memcpy(tex->data, aframe.pixels, tex->width*tex->height*4);
|
||||
// JS_SetPropertyStr(js, frame, "texture", texture2js(js,tex));
|
||||
SDL_Surface *surf = SDL_CreateSurfaceFrom(aframe.ase->w, aframe.ase->h, SDL_PIXELFORMAT_RGBA32, aframe.pixels, aframe.ase->w*4);
|
||||
JS_SetPropertyStr(js, frame, "surface", SDL_Surface2js(js,surf));
|
||||
JS_SetPropertyStr(js, frame, "rect", rect2js(js,(rect){.x=0,.y=0,.w=1,.h=1}));
|
||||
JS_SetPropertyStr(js, frame, "time", number2js(js,(float)aframe.duration_milliseconds/1000.0));
|
||||
return frame;
|
||||
@@ -2969,14 +2951,30 @@ JSC_CCALL(os_make_plane,
|
||||
return parmesh2js(js,par_shapes_create_plane(js2number(js,argv[0]), js2number(js,argv[1])));
|
||||
)
|
||||
|
||||
static void render_frame(plm_t *mpeg, plm_frame_t *frame, datastream *ds) {
|
||||
if (JS_IsUndefined(ds->callback)) return;
|
||||
uint8_t *rgb = malloc(frame->height*frame->width*4);
|
||||
memset(rgb,255,frame->height*frame->width*4);
|
||||
plm_frame_to_rgba(frame, rgb, frame->width*4);
|
||||
SDL_Surface *surf = SDL_CreateSurfaceFrom(frame->width,frame->height, SDL_PIXELFORMAT_RGBA32, rgb, frame->width*4);
|
||||
JSValue s[1];
|
||||
s[0] = SDL_Surface2js(ds->js,surf);
|
||||
JSValue cb = JS_DupValue(ds->js,ds->callback);
|
||||
JSValue ret = JS_Call(ds->js, cb, JS_UNDEFINED, 1, s);
|
||||
JS_FreeValue(ds->js,ret);
|
||||
JS_FreeValue(ds->js,cb);
|
||||
free(rgb);
|
||||
}
|
||||
|
||||
JSC_CCALL(os_make_video,
|
||||
size_t len;
|
||||
void *data = JS_GetArrayBuffer(js,&len,argv[0]);
|
||||
datastream *ds = ds_openvideo(data, len);
|
||||
ret = datastream2js(js,ds);
|
||||
texture *t = malloc(sizeof(texture));
|
||||
// t->id = ds->img;
|
||||
// JS_SetPropertyStr(js, ret, "texture", texture2js(js,t));
|
||||
if (!ds) return JS_ThrowReferenceError(js, "Video file was not valid.");
|
||||
ds->js = js;
|
||||
ds->callback = JS_UNDEFINED;
|
||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||
return datastream2js(js,ds);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_skin_calculate,
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
|
||||
#include "jsffi.h"
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#include "jsffi.h"
|
||||
|
||||
unsigned short pack_short_tex(float c) { return c * USHRT_MAX; }
|
||||
|
||||
SDL_GPUBuffer *texcoord_floats(float *f, int n)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "transform.h"
|
||||
#include "gameobject.h"
|
||||
#include "anim.h"
|
||||
#include "texture.h"
|
||||
#include "cgltf.h"
|
||||
|
||||
#define MAT_POS 0
|
||||
|
||||
168
source/texture.c
168
source/texture.c
@@ -1,168 +0,0 @@
|
||||
#include "texture.h"
|
||||
|
||||
#include "render.h"
|
||||
#include <math.h>
|
||||
#include <stb_image.h>
|
||||
#include <stb_image_write.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stb_image_resize2.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <tracy/TracyC.h>
|
||||
|
||||
#include "qoi.h"
|
||||
|
||||
|
||||
struct rect ST_UNIT = {0.f, 0.f, 1.f, 1.f};
|
||||
|
||||
unsigned int next_pow2(unsigned int v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
int mip_levels(int width, int height)
|
||||
{
|
||||
int levels = 0;
|
||||
|
||||
while (width > 1 || height > 1)
|
||||
{
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
levels++;
|
||||
}
|
||||
return levels;
|
||||
}
|
||||
|
||||
int mip_wh(int w, int h, int *mw, int *mh, int lvl)
|
||||
{
|
||||
w >>= lvl;
|
||||
h >>= lvl;
|
||||
|
||||
if (w == 0 && h == 0)
|
||||
return 1;
|
||||
|
||||
*mw = w ? w : 1;
|
||||
*mh = h ? h : 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void texture_offload(texture *tex)
|
||||
{
|
||||
if (tex->data) {
|
||||
TracyCFreeN(tex->data, "texture");
|
||||
free(tex->data);
|
||||
tex->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void texture_free(JSRuntime *rt, texture *tex)
|
||||
{
|
||||
if (!tex) return;
|
||||
texture_offload(tex);
|
||||
free(tex);
|
||||
}
|
||||
|
||||
struct texture *texture_empty(int w, int h)
|
||||
{
|
||||
int n = 4;
|
||||
texture *tex = calloc(1,sizeof(*tex));
|
||||
tex->data = calloc(w*h*n, sizeof(unsigned char));
|
||||
tex->width = w;
|
||||
tex->height = h;
|
||||
TracyCAllocN(tex->data, tex->height*tex->width*4, "texture");
|
||||
return tex;
|
||||
}
|
||||
|
||||
struct texture *texture_fromdata(void *raw, long size)
|
||||
{
|
||||
struct texture *tex = calloc(1, sizeof(*tex));
|
||||
|
||||
int n;
|
||||
void *data = stbi_load_from_memory(raw, size, &tex->width, &tex->height, &n, 4);
|
||||
|
||||
if (data == NULL) {
|
||||
free(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex->data = data;
|
||||
TracyCAllocN(tex->data, tex->height*tex->width*4, "texture");
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void texture_save(texture *tex, const char *file)
|
||||
{
|
||||
if (!tex->data) return;
|
||||
|
||||
char *ext = strrchr(file, '.');
|
||||
if (!strcmp(ext, ".png"))
|
||||
stbi_write_png(file, tex->width, tex->height, 4, tex->data, 4*tex->width);
|
||||
else if (!strcmp(ext, ".bmp"))
|
||||
stbi_write_bmp(file, tex->width, tex->height, 4, tex->data);
|
||||
else if (!strcmp(ext, ".tga"))
|
||||
stbi_write_tga(file, tex->width, tex->height, 4, tex->data);
|
||||
else if (!strcmp(ext, ".jpg") || !strcmp(ext, ".jpeg"))
|
||||
stbi_write_jpg(file, tex->width, tex->height, 4, tex->data, 5);
|
||||
else if (!strcmp(ext, ".qoi"))
|
||||
qoi_write(file, tex->data, &(qoi_desc) {
|
||||
.width = tex->width,
|
||||
.height = tex->height,
|
||||
.channels = 4,
|
||||
.colorspace = QOI_SRGB
|
||||
});
|
||||
}
|
||||
|
||||
texture *texture_scale(texture *tex, int width, int height)
|
||||
{
|
||||
texture *new = calloc(1, sizeof(*new));
|
||||
new->width = width;
|
||||
new->height = height;
|
||||
new->data = malloc(4*width*height);
|
||||
|
||||
stbir_resize_uint8_linear(tex->data, tex->width, tex->height, 0, new->data, width, height, 0, 4);
|
||||
return new;
|
||||
}
|
||||
|
||||
/*sapp_icon_desc texture2icon(texture *tex)
|
||||
{
|
||||
sapp_icon_desc desc = {0};
|
||||
if (!tex->data) return desc;
|
||||
struct isize {
|
||||
int size;
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
struct isize sizes[4];
|
||||
sizes[0].size = 16;
|
||||
sizes[1].size = 32;
|
||||
sizes[2].size = 64;
|
||||
sizes[3].size = 128;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sizes[i].data = malloc(4*sizes[i].size*sizes[i].size);
|
||||
stbir_resize_uint8_linear(tex->data, tex->width, tex->height, 0, sizes[i].data, sizes[i].size, sizes[i].size, 0, 4);
|
||||
}
|
||||
|
||||
desc = (sapp_icon_desc){
|
||||
.images = {
|
||||
{ .width = sizes[0].size, .height = sizes[0].size, .pixels = { .ptr=sizes[0].data, .size=4*sizes[0].size*sizes[0].size } },
|
||||
{ .width = sizes[1].size, .height = sizes[1].size, .pixels = { .ptr=sizes[1].data, .size=4*sizes[1].size*sizes[1].size } },
|
||||
{ .width = sizes[2].size, .height = sizes[2].size, .pixels = { .ptr=sizes[2].data, .size=4*sizes[2].size*sizes[2].size } },
|
||||
{ .width = sizes[3].size, .height = sizes[3].size, .pixels = { .ptr=sizes[3].data, .size=4*sizes[3].size*sizes[3].size } },
|
||||
}
|
||||
};
|
||||
|
||||
return desc;
|
||||
}
|
||||
*/
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include "HandmadeMath.h"
|
||||
#include "render.h"
|
||||
#include <quickjs.h>
|
||||
#include "stb_rect_pack.h"
|
||||
#include <SDL3/SDL_render.h>
|
||||
|
||||
#define TEX_SPEC 0
|
||||
#define TEX_NORM 1
|
||||
#define TEX_HEIGHT 2
|
||||
#define TEX_DIFF 3
|
||||
|
||||
#define FILTER_NEAREST SG_FILTER_NEAREST
|
||||
#define FILTER_NONE SG_FILTER_NONE
|
||||
#define FILTER_LINEAR SG_FILTER_LINEAR
|
||||
|
||||
extern struct rect ST_UNIT;
|
||||
|
||||
/* Represents an actual texture on the GPU */
|
||||
struct texture {
|
||||
SDL_Texture *id;
|
||||
SDL_Surface *surface;
|
||||
int width;
|
||||
int height;
|
||||
HMM_Vec3 dimensions;
|
||||
unsigned char *data;
|
||||
int vram;
|
||||
};
|
||||
|
||||
typedef struct texture texture;
|
||||
|
||||
typedef struct img_sampler{
|
||||
int wrap_u;
|
||||
int wrap_v;
|
||||
int wrap_w;
|
||||
int min_filter;
|
||||
int mag_filter;
|
||||
int mip_filter;
|
||||
} img_sampler;
|
||||
|
||||
texture *texture_fromdata(void *raw, long size);
|
||||
texture *texture_empty(int width, int height); // Make an empty texture
|
||||
texture *texture_dup(texture *tex); // return an identical texture
|
||||
texture *texture_scale(texture *tex, int width, int height); // dup and scale the texture
|
||||
|
||||
void texture_free(JSRuntime *rt,texture *tex);
|
||||
void texture_offload(texture *tex); // Remove the data from this texture
|
||||
|
||||
void texture_save(texture *tex, const char *file); // save the texture data to the given file
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user