video rendering

This commit is contained in:
John Alanbrook 2023-05-19 14:55:57 +00:00
parent 630d823591
commit 49271b4a5d
7 changed files with 88 additions and 81 deletions

View file

@ -75,9 +75,9 @@ void model_init() {
.attrs = { .attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT3, [0].format = SG_VERTEXFORMAT_FLOAT3,
[0].buffer_index = 0, /* position */ [0].buffer_index = 0, /* position */
[1].format = SG_VERTEXFORMAT_FLOAT2, [1].format = SG_VERTEXFORMAT_USHORT2N,
[1].buffer_index = 1, /* tex coords */ [1].buffer_index = 1, /* tex coords */
[2].format = SG_VERTEXFORMAT_FLOAT3, [2].format = SG_VERTEXFORMAT_UINT10_N2,
[2].buffer_index = 2, /* normal */ [2].buffer_index = 2, /* normal */
}, },
}, },
@ -107,6 +107,24 @@ cgltf_attribute *get_attr_type(cgltf_primitive p, cgltf_attribute_type t)
return NULL; return NULL;
} }
unsigned short pack_short_texcoord(float c)
{
return c * USHRT_MAX;
}
uint32_t pack_int10_n2(float *norm)
{
uint32_t ni[3];
for (int i = 0; i < 3; i++) {
ni[i] = fabs(norm[i]) * 511.0 + 0.5;
ni[i] = (ni[i] > 511) ? 511 : ni[i];
ni[i] = ( norm[i] < 0.0 ) ? -ni[i] : ni[i];
}
return (ni[0] & 0x3FF) | ( (ni[1] & 0x3FF) << 10) | ( (ni[2] & 0x3FF) << 20) | ( (0 & 0x3) << 30);
}
struct model *MakeModel(const char *path) { struct model *MakeModel(const char *path) {
YughWarn("Making the model from %s.", path); YughWarn("Making the model from %s.", path);
cgltf_options options = {0}; cgltf_options options = {0};
@ -189,6 +207,9 @@ struct model *MakeModel(const char *path) {
cgltf_accessor_unpack_floats(attribute.data, vs, n); cgltf_accessor_unpack_floats(attribute.data, vs, n);
uint32_t *packed_norms;
unsigned short *packed_coords;
switch (attribute.type) { switch (attribute.type) {
case cgltf_attribute_type_position: case cgltf_attribute_type_position:
model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
@ -198,25 +219,37 @@ struct model *MakeModel(const char *path) {
case cgltf_attribute_type_normal: case cgltf_attribute_type_normal:
has_norm = 1; has_norm = 1;
packed_norms = malloc(model->meshes[j].face_count * sizeof(uint32_t));;
for (int i = 0; i < model->meshes[j].face_count; i++)
packed_norms[i] = pack_int10_n2(vs + i*3);
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){ model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
.data.ptr = vs, .data.ptr = packed_norms,
.data.size = sizeof(float) * n}); .data.size = sizeof(uint32_t) * model->meshes[j].face_count});
free (packed_norms);
break; break;
case cgltf_attribute_type_tangent: case cgltf_attribute_type_tangent:
break; break;
case cgltf_attribute_type_texcoord: case cgltf_attribute_type_texcoord:
packed_coords = malloc(model->meshes[j].face_count * 2 * sizeof(unsigned short));
for (int i = 0; i < model->meshes[j].face_count*2; i++)
packed_coords[i] = pack_short_texcoord(vs[i]);
model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
.data.ptr = vs, .data.ptr = vs,
.data.size = sizeof(float) * n}); .data.size = sizeof(unsigned short) * 2 * model->meshes[j].face_count});
free(packed_coords);
break; break;
} }
} }
if (!has_norm) { if (!has_norm) {
YughWarn("Model does not have normals. Generating them."); YughWarn("Model does not have normals. Generating them.");
float norms[3 * model->meshes[j].face_count]; uint32_t norms[model->meshes[j].face_count];
cgltf_attribute *pa = get_attr_type(primitive, cgltf_attribute_type_position); cgltf_attribute *pa = get_attr_type(primitive, cgltf_attribute_type_position);
@ -224,24 +257,23 @@ struct model *MakeModel(const char *path) {
float ps[n]; float ps[n];
cgltf_accessor_unpack_floats(pa->data,ps,n); cgltf_accessor_unpack_floats(pa->data,ps,n);
for (int i = 0; i < model->meshes[j].face_count/3; i++) { for (int i = 0, face=0; i < model->meshes[j].face_count/3; i++, face+=9) {
int o = i*9; int o = face;
HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]}; HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]};
o += 3; o += 3;
HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]}; HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]};
o += 3; o += 3;
HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]}; HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]};
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a))); HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
for (int j = 0; j < 3; j++) {
norms[i*9+j*3+0] = norm.X; uint32_t packed_norm = pack_int10_n2(norm.Elements);
norms[i*9+j*3+1] = norm.Y; for (int j = 0; j < 3; j++)
norms[i*9+j*3+2] = norm.Z; norms[i*3+j] = packed_norm;
}
} }
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){ model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
.data.ptr = norms, .data.ptr = norms,
.data.size = sizeof(float) * model->meshes[j].face_count * 3 .data.size = sizeof(uint32_t) * model->meshes[j].face_count
}); });
} }
} }

View file

@ -14,24 +14,26 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
struct shader *vid_shader; #include "sokol/sokol_gfx.h"
sg_shader vid_shader;
sg_pipeline vid_pipeline;
sg_bindings vid_bind;
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t *plane) {
/*
glActiveTexture(unit);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, plane->width, plane->height, 0, GL_RED, GL_UNSIGNED_BYTE, plane->data);
*/
}
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) { static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
struct datastream *ds = user; struct datastream *ds = user;
shader_use(ds->shader); uint8_t rgb[frame->height*frame->width*4];
/* plm_frame_to_rgba(frame, rgb, frame->width*4);
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y); sg_image_data imgd;
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb); sg_range ir = {
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr); .ptr = rgb,
*/ .size = frame->height*frame->width*4*sizeof(uint8_t)
};
imgd.subimage[0][0] = ir;
sg_update_image(ds->img, &imgd);
} }
static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) { static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
@ -44,16 +46,6 @@ static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
} }
} }
struct Texture *ds_maketexture(struct datastream *ds) {
/*
struct Texture *new = malloc(sizeof(*new));
new->id = ds->texture_cb;
new->width = 500;
new->height = 500;
return new;
*/
}
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) { void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
// ds_stop(ds); // ds_stop(ds);
char buf[MAXPATH] = {'\0'}; char buf[MAXPATH] = {'\0'};
@ -64,6 +56,11 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
YughLog(0, 0, "Couldn't open %s", video); YughLog(0, 0, "Couldn't open %s", video);
} }
ds->img = sg_make_image(&(sg_image_desc){
.width = plm_get_width(ds->plm),
.height = plm_get_height(ds->plm)
});
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f", YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
video, video,
plm_get_framerate(ds->plm), plm_get_framerate(ds->plm),
@ -107,37 +104,14 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
} }
struct datastream *MakeDatastream() { struct datastream *MakeDatastream() {
struct datastream *newds = malloc(sizeof(*newds)); vid_shader = sg_make_shader(&(sg_shader_desc){
/* .vs.source = slurp_text("shaders/videovert.glsl"),
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl"); .fs.source = slurp_text("shaders/videofrag.glsl"),
.fs.images[0] = {
newds->shader = vid_shader; .name = "video",
shader_use(newds->shader); .image_type = SG_IMAGETYPE_2D,
glGenTextures(1, &newds->texture_y); .sampler_type = SG_SAMPLERTYPE_FLOAT
glBindTexture(GL_TEXTURE_2D, newds->texture_y); }});
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
shader_setint(newds->shader, "texture_y", 0);
glGenTextures(1, &newds->texture_cb);
glBindTexture(GL_TEXTURE_2D, newds->texture_cb);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
shader_setint(newds->shader, "texture_cb", 1);
glGenTextures(1, &newds->texture_cr);
glBindTexture(GL_TEXTURE_2D, newds->texture_cr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
shader_setint(newds->shader, "texture_cr", 2);
*/
return newds;
} }
void ds_advance(struct datastream *ds, double s) { void ds_advance(struct datastream *ds, double s) {

View file

@ -4,24 +4,23 @@
#include <pl_mpeg.h> #include <pl_mpeg.h>
#include <stdint.h> #include <stdint.h>
#include "sokol/sokol_gfx.h"
struct soundstream; struct soundstream;
struct datastream { struct datastream {
plm_t *plm; plm_t *plm;
struct shader *shader;
double last_time; double last_time;
int playing; int playing;
int audio_device; int audio_device;
uint32_t texture_y; sg_image img;
uint32_t texture_cb; int width;
uint32_t texture_cr; int height;
struct soundstream *astream; struct soundstream *astream;
}; };
struct Texture; struct Texture;
extern struct shader *vid_shader;
struct datastream *MakeDatastream(); struct datastream *MakeDatastream();
void ds_openvideo(struct datastream *ds, const char *path, const char *adriver); void ds_openvideo(struct datastream *ds, const char *path, const char *adriver);
struct Texture *ds_maketexture(struct datastream *); struct Texture *ds_maketexture(struct datastream *);

View file

@ -215,7 +215,7 @@ void text_flush() {
if (curchar == 0) return; if (curchar == 0) return;
sg_apply_pipeline(pipe_text); sg_apply_pipeline(pipe_text);
sg_apply_bindings(&bind_text); sg_apply_bindings(&bind_text);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection)); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
sg_range verts; sg_range verts;
verts.ptr = text_buffer; verts.ptr = text_buffer;

View file

@ -40,6 +40,7 @@ float gridOpacity = 0.3f;
mfloat_t proj[16]; mfloat_t proj[16];
// Debug render modes // Debug render modes
bool renderGizmos = false; bool renderGizmos = false;
bool showGrid = true; bool showGrid = true;
@ -233,6 +234,7 @@ float cam_zoom() { return zoom; }
void add_zoom(float val) { zoom = val; } void add_zoom(float val) { zoom = val; }
mfloat_t projection[16] = {0.f}; mfloat_t projection[16] = {0.f};
float hudproj[16] = {0.f};
HMM_Vec3 dirl_pos = {4, 100, 20}; HMM_Vec3 dirl_pos = {4, 100, 20};
@ -281,8 +283,7 @@ void openglRender(struct window *window) {
pos.y - zoom * window->height / 2, pos.y - zoom * window->height / 2,
pos.y + zoom * window->height / 2, -1.f, 1.f); pos.y + zoom * window->height / 2, -1.f, 1.f);
mfloat_t ui_projection[16] = {0.f}; mat4_ortho(hudproj, 0, window->width, 0, window->height, -1.f, 1.f);
mat4_ortho(ui_projection, 0, window->width, 0, window->height, -1.f, 1.f);
sprite_draw_all(); sprite_draw_all();
sprite_flush(); sprite_flush();

View file

@ -19,6 +19,7 @@ extern int renderMode;
extern HMM_Vec3 dirl_pos; extern HMM_Vec3 dirl_pos;
extern float projection[16]; extern float projection[16];
extern float hudproj[16];
extern float gridScale; extern float gridScale;
extern float smallGridUnit; extern float smallGridUnit;

View file

@ -217,15 +217,15 @@ void sprite_setframe(struct sprite *sprite, struct glrect *frame) {
} }
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3]) { void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3]) {
shader_use(vid_shader); // shader_use(vid_shader);
static mfloat_t model[16]; static mfloat_t model[16];
memcpy(model, UNITMAT4, sizeof(UNITMAT4)); memcpy(model, UNITMAT4, sizeof(UNITMAT4));
mat4_translate_vec2(model, position); mat4_translate_vec2(model, position);
mat4_scale_vec2(model, size); mat4_scale_vec2(model, size);
shader_setmat4(vid_shader, "model", model); // shader_setmat4(vid_shader, "model", model);
shader_setvec3(vid_shader, "spriteColor", color); // shader_setvec3(vid_shader, "spriteColor", color);
/* /*
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, stream->texture_y); glBindTexture(GL_TEXTURE_2D, stream->texture_y);